帮助核心数据制作NSPredicate - 递归搜索

时间:2010-08-02 23:38:16

标签: iphone core-data nspredicate

我正在将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被返回,因为我只检查了一个级别。有没有办法让谓词对整个链进行检查?

感谢。

3 个答案:

答案 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]];