我正在为iPhone项目使用CoreData,但我一直试图建立一个谓词。
我的核心数据实体是
Folder
parent - Point to the folder class parent, can be null and is one to one.
secure - An enum that holds the security type.
我遇到的问题是我正在尝试使其不显示安全文件夹中的任何文件夹。
现在我的谓词看起来像这样。
NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = $@ AND (parent = %@ OR parent.secure = %@)",[NSNumber numberWithInteger:kNoSecurity], [NSNull null], [NSNumber numberWithInteger:kNoSecurity]];
当我只有像folder1-> folder2这样的链并且folder1是安全的时,这种方法可以找到。但是,如果我有folder1-> folder2-> folder3(文件夹2和folder3不安全)。 Folder3被返回,因为我只检查了一个级别。有没有办法让谓词对整个链条进行检查?
谢谢。
最佳答案
问题是,这只会上升
一级。所以如果我有folder1->
folder2-> folder3-> folder4,以及
folder1是安全的。那么folder2不是
显示,但folder3和folder4是。
您不能递归遍历谓词中的关系,因为键路径仅描述抽象实体之间的关系,而不能描述实际包含数据的具体的,活动的托管对象。实体图可能非常简单,但在运行时填充时会生成非常复杂的活动对象图。您不能通过简单的键路径从逻辑上捕获该实时图的复杂性。
在这种情况下,您有一个Folder
实体,该实体与本身具有关系,称为parent
,并且具有secure
属性。因此,键路径最多只能使用路径parent.secure
描述这两个属性。您不能创建parent.parent.secure
的键路径,因为实体图中实际上不存在这样的关系。这样的路径有时仅存在于活动对象图中。从逻辑上讲,在任何给定时间根据数据的具体情况对可能存在或不存在的路径进行硬编码都是不可能的。
在这种情况下,创建自定义NSManagedObject子类的功能非常有用。您的Folder
实体不必只是愚蠢的数据,您可以向它们添加行为,以便每个对象可以访问自己的状态并根据需要返回不同的数据。
在这种情况下,我建议添加一个名为hasSecureAncestor
之类的瞬态布尔属性。然后创建一个自定义getter方法,例如:
- (BOOL) hasSecureAncestor{
BOOL hasSecureAncestor=NO;
if (self.parent.secure==kNoSecurity) {
hasSecureAncestor=YES;
}else {
if (self.parent.parent!=nil) {
hasSecureAncestor=self.parent.hasSecureAncestor;
}else {
hasSecureAncestor=NO;
}
}
return hasSecureAncestor;
}
然后只需创建一个谓词以测试“ hasSecureAncestor == YES”。定制访问器将遍历任意深度的递归关系,以寻找安全的祖先。
关于iphone - 帮助CoreData制作NSPredicate-递归搜索,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3392587/