2010-08-02 28 views
2

我正在使用CoreData的iPhone項目,我卡住試圖建立一個謂詞。幫助核心數據做一個NSPredicate - 遞歸搜索

我的核心數據實體是

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 = [email protected] AND (parent = %@ OR parent.secure = %@)",[NSNumber numberWithInteger:kNoSecurity], [NSNull null], [NSNumber numberWithInteger:kNoSecurity]]; 

這個作品發現,當我只有像folder1 - > folder2和folder1是安全的鏈。但是,如果我有文件夾1 - >文件夾2 - >文件夾3(文件夾2和文件夾3不安全)。 Folder3被返回,因爲我只檢查一層。有沒有辦法讓謂詞來檢查整個鏈?

謝謝。

回答

3

的問題是,這只是上升 一個級別。所以如果我有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」。自定義訪問者將走一個任意深度的遞歸關係尋找一個安全的祖先。

+0

我沒有遵循這個建議,我做了一個祖先表,因爲我的真實代碼有一些要求沒有在這裏陳述。但是這裏提出的建議可以解決所述問題。 – NixonsBack 2010-08-06 18:36:08

+0

是否真的有可能創建一個訪問瞬態屬性的NSPredicate?我讀過的其他東西說,它不會工作,至少不會與SQLite商店。 (請參閱[this](http://stackoverflow.com/a/15972685/234609)和[this](http://www.cocoabuilder.com/archive/cocoa/237109-only-one-reason-to-ever -use瞬態 - 屬性 - 在覈心-data.html))。 – 2016-05-24 15:06:43

1

爲什麼不只是抓住所有與kNoSecurity文件夾實體?

NSPredicate *pred = [NSPredicate predicateWithFormat:@"secure = %@ ", [NSNumber numberWithInteger:kNoSecurity]]; 
+0

似乎evanchri不想選擇具有安全的父文件夾(在任何級別)的文件夾。 – 2010-08-03 00:22:43

+0

Seamus你是對的。我只想查看不在安全文件夾中的文件夾。 – NixonsBack 2010-08-03 00:37:07

+0

我不確定你只能用一個謂詞封裝它。如果任何父文件夾是安全的,或者您位於文件夾樹的根目錄下,則可能需要執行遞歸搜索並停止。 – 2010-08-03 19:54:16

0

如何回去了通過關係:

NSPredicate *pred = [NSPredicate predicateWithFormat:"parent.secure = %@", [NSNumber numberWithInteger:kNoSecurity]]; 
+0

感謝您的回覆。我在我的代碼中這樣做,我只是忘了在這裏添加到我的代碼中。問題是這只是上升到一個層次。所以如果我有folder1 - > folder2 - > folder3 - > folder4,並且folder1是安全的。然後folder2不顯示,但folder3和folder4是。 – NixonsBack 2010-08-03 16:44:21