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

Posted

技术标签:

【中文标题】核心数据 NSPredicate“已删除 == NO”无法按预期工作【英文标题】:Core Data NSPredicate "deleted == NO" does not work as expected 【发布时间】:2013-04-14 14:39:31 【问题描述】:

我正在使用带有父子上下文的 UIManagedDocument。

在我的子上下文中,我执行以下操作

代码 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 的优缺点是什么?

【问题讨论】:

【参考方案1】:

问题是您已经为您的实体定义了一个属性deleted。这与NSManagedObjectisDeleted 方法冲突,因此您应该重命名该属性。

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

// 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

您的“代码 1”指的是属性,因此它返回预期结果。 “代码2”使用Key-Value编码,如果对象[c valueForKey:@"deleted"]返回YES 实际上已经从上下文中删除了!

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

【讨论】:

谢谢,它成功了。但 isDeleted 和 deleted 是两个不同的名称。当我检查 NSManagedObject.h 头文件 // state - methods can be used through KVC, for example for enabling/disabling widgets based on the state of the object - (BOOL)isInserted; - (BOOL)isUpdated; - (BOOL)isDeleted; 可能是苹果有一些私有财产,如【参考方案2】:

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

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

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

【讨论】:

[NSPredicate predicateWithFormat:@"%K == %@", @"deleted", @(NO)][NSPredicate predicateWithFormat:@"deleted == NO"]一样,没有区别。

以上是关于核心数据 NSPredicate“已删除 == NO”无法按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

日期的核心数据 NSPredicate

使用 NSPredicate 进行核心数据实体搜索

核心数据和 NSPredicate

NSPredicate - 核心数据 - 比较两个属性

核心数据 - 为啥我的 NSPredicate 没有产生正确的 SQL 查询?

核心数据。使用常量文字作为属性名称的 NSPredicate 问题