【发布时间】:2011-08-10 14:28:00
【问题描述】:
我有一个ManagedObject class,班级的成员之一是NSDate。我想显示未设置日期的类的所有对象。我尝试使用这样的谓词:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(date = NIL)"];
但我仍然得到设置了date 的对象。为此设置谓词的正确方法是什么?
【问题讨论】:
我有一个ManagedObject class,班级的成员之一是NSDate。我想显示未设置日期的类的所有对象。我尝试使用这样的谓词:
NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(date = NIL)"];
但我仍然得到设置了date 的对象。为此设置谓词的正确方法是什么?
【问题讨论】:
我认为这是区分大小写的问题。您可以使用“nil”或“NULL”,但不能使用“NIL”。这对我来说很好:
NSPredicate *eventWithNoEndDate = [NSPredicate predicateWithFormat:@"endDate = nil"];
【讨论】:
= 和== 是等价的,但developer.apple.com/library/mac/documentation/Cocoa/Conceptual/… 中的示例使用=
=和==在谓词内是等价的
想通了。无法通过使用具有字符串格式的谓词来做到这一点,因此尝试了带有模板的谓词并且它起作用了。下面的代码给了我将 endDate 设置为 NULL 的对象:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"endDate = $DATE"];
predicate = [predicate predicateWithSubstitutionVariables:
[NSDictionary dictionaryWithObject:[NSNull null] forKey: @"DATE"]];
【讨论】:
以下代码应该可以工作
predicate = [NSPredicate predicateWithFormat:@"firstName = nil"];
【讨论】:
正如 Apple 所记录的,获取请求的行为非常烦人:
如果上下文中的对象已被修改,则根据其修改后的状态评估谓词,而不是根据持久存储中的当前状态评估谓词。因此,如果上下文中的对象已被修改以使其满足获取请求的条件,则即使更改尚未保存到存储并且存储中的值不满足条件,请求也会检索它。相反,如果上下文中的对象已被修改,使其与获取请求不匹配,则即使存储中的版本匹配,获取请求也不会检索它。
您可能正在其他地方清除日期,并且获取请求包括日期为内存中 nil 但仍设置在磁盘上(在持久存储中)的结果,因此当对象出现故障时,它会加载对象与日期设置。
我唯一的建议是协调对托管对象上下文的访问(例如,在NSOperationQueue 上),以便在执行获取请求之前能够将任何更新保存到持久存储中。
【讨论】: