NSNumber 类型的托管属性?未初始化为零

Posted

技术标签:

【中文标题】NSNumber 类型的托管属性?未初始化为零【英文标题】:Managed property of type NSNumber? not initialized to nil 【发布时间】:2017-02-14 12:06:22 【问题描述】:

我的 Swift 3 应用使用 CoreData。自从过渡到 Swift3/Xcode 8 以来,我已经放弃了 NSManagedObject 子类的自动代码生成(新行为,我还没有完全弄清楚),所以我只是指定非/手动并创建自己的类。到目前为止一切顺利。

我将所有标量属性存储在NSNumber? 属性中,而不是可选的标量类型,如Int?Double? 等(我不确定可选的标量属性是否适用于Core Data...? )。

问题是,我无法检测到新创建的对象中属性的“尚未设置值”状态。

例如,我有:

class MyClass: NSManagedObject 

    // Stores a double
    @NSManaged var length: NSNumber?

每当我尝试访问该值时,我永远不会得到nil,而是0.0

if let value = myObject.length?.doubleValue 
    // Always gets executes and value 0.0 is unwrapped
    // for new objects
 else 
    // Never gets executed

但是,如果我在实例插入时手动将其设置为 nil,即:

override awakeFromInsert()

    super.awakeFromInsert()

    // Explicitly set to nil:
    self.length = nil

...然后,我得到了预期的行为。

我错过了什么吗?

我猜@NSManaged 属性在很多方面都与普通的 swift 可选属性不同......但我在任何地方都找不到这种行为的提及。

【问题讨论】:

属性是否可以为空? 你是否在 Core Data 模型检查器中为属性定义了一个默认值 哦,是的。即使我使用 NSNumber 手动生成代码,“使用标量类型”的复选框也被选中,默认值设置为零! :0 愚蠢的我。我想就是这样。我确实也选中了“可选”框... 这是 Swift:默认值为零! :0 != nil(无值)。 【参考方案1】:

我同意 Arun 的观点,即您需要选择一种类型(事实上,如果您不这样做,您应该会收到错误消息)。

至于您的问题,CoreData 默认为数字字段添加默认值。但是,您可以使用数据模型检查器指示它不设置默认值,如下所示:

如果您在创建新记录时关闭了默认设置并将该字段留空,请确保同时选中可选复选框(在默认复选框上方几行)。

此外,如果您在第一次部署后添加了没有默认值的必填字段,则您需要自己处理迁移,因为轻量迁移在向现有数据库添加新的必填字段时依赖默认值。

【讨论】:

正在选择一种类型(Integer16、Double 等)。我只是在我的类定义中使用 NSNumber。不确定替代方案;我对想法持开放态度(到处拆箱 NSNumber 很麻烦)【参考方案2】:

从 core-data .xcmod​​el 类中选择时,您不能选择 NSNumber 作为数据类型。创建属性时,您定义了一个默认值。下面是提到默认值类型的屏幕截图。 因此,如果您希望长度中的值作为 double 选择 double 作为默认值。

从 Xcode 创建托管类。 Xcode->Editor->创建 NSManagedObject 子类。您会自动生成类。

【讨论】:

以上是关于NSNumber 类型的托管属性?未初始化为零的主要内容,如果未能解决你的问题,请参考以下文章

全局对象内的内置类型的成员变量是不是已初始化为零?

为啥 int 数组在 C++ 中未初始化为零?

为啥我的内核的共享内存似乎初始化为零?

列表初始化是不是将原子初始化为零?

C语言 | 每日基础

《你必须知道的495个C语言问题》笔记