Iphone n预测比较键,其中一个可能为零
我有一个Iphone n预测比较键,其中一个可能为零,iphone,ios,core-data,nspredicate,nsmanagedobject,Iphone,Ios,Core Data,Nspredicate,Nsmanagedobject,我有一个NSManagedObject子类Foo,它有两个建模属性:a和b a和b是NSStrings,但不能保证它们会被实例化——它们也可以是nil。事实上,正如现在发生的那样,所有Foo实例的b都等于nil 我想获取所有Foo对象,以便a!=b: NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Foo"]; fetchRequest.predicate = [NSPredicate pre
NSManagedObject
子类Foo
,它有两个建模属性:a
和b
a
和b
是NSString
s,但不能保证它们会被实例化——它们也可以是nil
。事实上,正如现在发生的那样,所有Foo
实例的b
都等于nil
我想获取所有Foo
对象,以便a!=b
:
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Foo"];
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"a != b"];
NSArray *result = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
结果数组是空的,即使我知道有10个对象的a
肯定是而不是nil
事实上,我甚至可以通过将谓词调整为:
fetchRequest.predicate = [NSPredicate predicateWithFormat:@"a != nil"];
这很好,并返回给我的10个对象
NSPredicate
/NSFetchRequest
的这种行为非常奇怪,我不明白为什么它会为原始a!=b
谓词,其中b
为null
。但当我将其更改为a!=nil
(这只是b
的硬编码值!!)
在编写了更多的测试代码来探讨这个问题之后,似乎在比较键时,如果=
属性的LHS或RHS为nil
,则生成的数组为空
另一方面,如果LHS和RHS都是非nil,那么它似乎工作正常
我错过了什么?为什么在比较两个键(其中一个或两个键都是
nil
)时,==
运算符失败?nil
值在SQLite数据库中存储为NULL
,SQLite将NULL
视为
“未定义值”。谓词“a!=b”被转换为SQLite查询
SELECT ... FROM ZENTITY t0 WHERE t0.ZA <> t0.ZB
使用“不是”而不是“是”。因此,这个查询实际上返回所有具有
a!=零
(正如人们所预料的那样)
我不知道核心数据文档中是否明确记录了这种行为
(我还没有搜索过),但SQLite就是这样处理空值的,它应该解释一下
你观察到的行为
如果添加启动参数,则可以看到SQLite语句
-com.apple.CoreData.SQLDebug 3
-com.apple.CoreData.SQLDebug 3
用于方案编辑器中的可执行文件
更新:来自“核心数据编程指南”:
您可以指定属性是可选的,也就是说,它不是可选的
需要有一个值。然而,总的来说,你会感到气馁
特别是对于数值(通常可以
使用具有默认值的强制属性可以获得更好的结果
模型(0)。这是因为SQL具有特殊的比较功能
与Objective-C的nil不同的NULL行为。数据库中的NULL
与0不同,对0的搜索将不匹配
空
这至少提到了可选属性是特殊的,可能不是
按预期行事
还有一个关于空值和空测试的部分。明白了!谢谢你的解释。我在核心数据文档中找不到这方面的任何参考。因此,除了将我的谓词重写为
(a==nil和b!=nil)或(a!=nil和b==nil)或(a!=b)
之外,还有什么简写吗?@jon:我找不到更简短的版本。
-com.apple.CoreData.SQLDebug 3