我正在将CoreData用于iPhone项目,而我却试图构建一个谓词。
我的核心数据实体是
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(folder2和folder3不安全)。 Folder3被返回,因为我只检查了一个级别。有没有办法让谓词对整个链进行检查?
感谢。
答案 0 :(得分:3)
问题是这只会上升 一级。所以,如果我有folder1 - > folder2 - > folder3 - > folder4,和 folder1是安全的。然后folder2不是 显示但是folder3和folder4是。
您无法在谓词中递归地遍历关系,因为键路径仅描述抽象实体之间的关系,而不描述实际包含数据的具体实时托管对象。实体图可以非常简单,但在运行时填充时会生成一个非常复杂的活动对象图。您无法使用简单的密钥路径逻辑捕获该实时图的复杂性。
在这种情况下,您有一个Folder
实体与自身有parent
的关系,属性为secure
。因此,密钥路径最多只能描述路径为parent.secure
的两个属性。您无法创建parent.parent.secure
的密钥路径,因为实体图中实际上不存在此类关系。这种路径有时仅存在于实时对象图中。根据任何给定时间的数据细节,在逻辑上不可能对可能存在或可能不存在的路径进行硬编码。
这种情况是创建自定义NSManagedObject子类的能力真正派上用场的地方。您的Folder
entites不必只是简单的数据,您可以向它们添加行为,以便每个对象可以访问自己的状态并根据需要返回不同的数据。
在这种情况下,我建议添加一个名为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”。自定义访问器将走一个任意深度的递归关系,寻找一个安全的祖先。
答案 1 :(得分:1)
为什么不抓住kNoSecurity
的所有文件夹实体?
NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = %@ ", [NSNumber numberWithInteger:kNoSecurity]];
答案 2 :(得分:0)
如何恢复关系:
NSPredicate *pred = [NSPredicate predicateWithFormat:"parent.secure = %@", [NSNumber numberWithInteger:kNoSecurity]];