在核心数据中存储可选的NSNumber

时间:2009-07-27 14:18:08

标签: iphone objective-c cocoa-touch core-data nsnumber

在我的核心数据模型中,我有一个具有可选NSNumber属性的实体。

如何测试该属性中的值是否有效?

当我测试nil时......不起作用。

[self numberAttribute] == nil // always returns NO

当我测试零值int时,这不起作用。

[[self numberAttribute] intValue] == 0  // always returns no

事实上,[[self numberAttribute] intValue]]返回的东西看起来像是指向内存地址的指针。

任何人都知道我做错了什么?

编辑:好的,这个错误与代码完全无关。 NSNumber和Core Data的功能完全符合预期。也就是说,我将采用建议的方法,使属性非可选,并指定0作为默认值。

对于正在观看此问题的人,请暂时将此说明放在此处,然后我将其删除。

3 个答案:

答案 0 :(得分:5)

根据documentation

  

您可以指定属性是可选的 - 也就是说,不需要具有值。但是,一般情况下,不鼓励您这样做 - 特别是对于数值(通常,您可以使用带有默认值的强制属性 - 在0的模型中获得更好的结果)。原因是SQL对NULL有特殊的比较行为,与Objective-C的nil不同。数据库中的NULL与0不同,搜索0将不匹配具有NULL的列。

false == (NULL == 0)
false == (NULL != 0)
  

此外,数据库中的NULL不等于空字符串或空数据blob:

false == (NULL == @"")
false == (NULL != @"")

因此,尝试使用NULL进行测试,这不是零。更好的是,设置默认值并将属性更改为非可选属性。这就是我最终在我的模型中所做的事情,并且在实践中它的效果非常好。

编辑: 请参阅上面的评论。我尝试创建一个未设置可选属性的新托管对象,它是零。

BOOL isNil = ([newManagedObject numberAttribute] == nil);  //equals YES

另一个编辑: 我稍后回过头来检查了调试器中缓存中加载的对象(gdb是你的朋友!)。它试图访问内存位置0x0,这是NULL。

答案 1 :(得分:0)

如果你得到一个看起来像指针的大值,也许它是NaN(不是数字)?

如果是这样,您可以查看:

 isnan([[self numberAttribute] doubleValue])

或者,它可能是NSNotFound的其他常量(尽管可能更具核心数据)。

答案 2 :(得分:0)

如果它看起来像指针,它可能是指向NSNumber实例的指针。确保核心数据模型与班级之间没有不匹配(例如NSInteger,其中NSNumber*是预期的。

如果你的班级有标量,那么你需要在setNilValueForKey:中注意到自己。