核心数据NSPredicate“已删除==否”无法按预期工作

时间:2013-04-14 14:39:31

标签: objective-c core-data nspredicate uimanageddocument

我正在使用UIManagedDocument和Parent Child上下文。

在我的孩子背景下,我做以下

代码1

NSSet *results = [self.event.memberships filteredSetUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {

    return ([[evaluatedObject deleted] boolValue] == NO);

}]];

以上代码返回预期结果(仅事件未删除成员)。

代码2

但是这段代码没有。它获取所有记录。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"deleted == NO"];
NSSet *results = [self.event.memberships filteredSetUsingPredicate:predicate];

这似乎令人困惑。两者都应返回相同的结果,但predicateWithBlock会返回正确的结果,而predicateWithFormat会返回所有记录。

使用predicateWithBlock代替predicateWithFormat有什么优缺点?

2 个答案:

答案 0 :(得分:7)

问题是您已为实体定义了属性deleted。这与isDeleted的{​​{1}}方法冲突,因此您应该重命名该属性。

以下“实验”表明,如果您将属性称为“已删除”,则会发生奇怪的事情(NSManagedObject是具有自定义c属性的托管对象):

deleted

您的“代码1”是指该属性,因此它返回预期结果。 “代码2”使用键值编码,// Set custom "deleted" property to YES: c.deleted = @YES; // Use the property, as your Code 1 NSLog(@"%@", [c deleted]); // Output: 1 // Use Key-Value Coding, as your Code 2 NSLog(@"%@", [c valueForKey:@"deleted"]); // Output: 0 // Now really delete the object and try again: [context deleteObject:c]; NSLog(@"%@", [c valueForKey:@"deleted"]); // Output: 1 如果对象返回[c valueForKey:@"deleted"] 实际上已从上下文中删除了!

因此,重命名该属性可以解决您的问题。不幸的是,编译器没有 如果属性名称与内置方法冲突,则发出警告。

答案 1 :(得分:0)

使用格式化占位符替换bool值:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)];

您对密钥路径的使用可能没问题,但右侧可能对解析器看起来不像“NO”。