2013-09-01 174 views
5

我有一個NSManagedObject與相關的對象。該關係由keyPath描述。NSFetchedResultsController包含關係對象

現在我想在表格視圖中顯示這些相關的對象。當然,我可以將NSSet與這些對象作爲數據源,但我更願意使用NSFetchedResultsController重新獲取對象以從其功能中受益。

如何創建描述這些對象的謂詞?

+0

請描述實體和關係,以及您想要顯示的內容。 –

+0

這應該不重要。我正在尋找一個基於對象和關係關鍵路徑的通用解決方案。 –

回答

13

要使用提取結果控制器顯示給定對象的相關對象,您可以在謂詞中使用反比關係。例如:

enter image description here

要顯示與給定父兒童,使用讀取的結果控制器 用下面的獲取請求:

Parent *theParent = ...; 
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Child"]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"parent = %@", theParent]; 
[request setPredicate:predicate]; 

對於嵌套關係,只要使用逆關係以相反的順序。例如:

enter image description here

要顯示一個特定國家的街道:

Country *theCountry = ...; 
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Street"]; 
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = %@", theCountry]; 
[request setPredicate:predicate]; 
+0

我究竟如何得到反比關係,特別是如果我有一個具有多個元素的關鍵路徑? –

+0

@de .:查看最新的答案。 –

+0

請參閱我自己的答案,以獲得關鍵路徑的通用方法。這看起來有點複雜,但我無法找到更簡單的核心數據API解決方案。 –

1

感謝馬丁,你給我的重要信息。

一般地得到我發現以下實施的關鍵路徑:

// assume to have a valid key path and object 
    NSString *keyPath; 
    NSManagedObject *myObject; 

    NSArray *keys = [keyPath componentsSeparatedByString:@"."]; 
    NSEntityDescription *entity = myObject.entity; 
    NSMutableArray *inverseKeys = [NSMutableArray arrayWithCapacity:keys.count]; 
    // for the predicate we will need to know if we're dealing with a to-many-relation 
    BOOL isToMany = NO; 
    for (NSString *key in keys) { 
     NSRelationshipDescription *inverseRelation = [[[entity relationshipsByName] valueForKey:key] inverseRelationship]; 
     // to-many on multiple hops is not supported. 
     if (isToMany) { 
      NSLog(@"ERROR: Cannot create a valid inverse relation for: %@. Hint: to-many on multiple hops is not supported.", keyPath); 
      return nil; 
     } 
     isToMany = inverseRelation.isToMany; 
     NSString *inverseKey = [inverseRelation name]; 
     [inverseKeys insertObject:inverseKey atIndex:0]; 
    } 
    NSString *inverseKeyPath = [inverseKeys componentsJoinedByString:@"."]; 
    // now I can construct the predicate 
    if (isToMany) { 
     predicate = [NSPredicate predicateWithFormat:@"ANY %K = %@", inverseKeyPath, self.dataObject]; 
    } 
    else { 
     predicate = [NSPredicate predicateWithFormat:@"%K = %@", inverseKeyPath, self.dataObject]; 
    } 

更新:我改變了謂詞格式,以便它也支持許多一對多的關係。

更新2這變得越來越複雜:我需要檢查我的逆關係,如果它是對多的並使用不同的謂詞。我更新了上面的代碼示例。

-2
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = '%@'", theCountry]; 

您錯過了''in predicateWithFormat字符串。現在它工作。

+0

這是不正確的。用引號''%@'',%@不會被參數擴展*。 –

+0

這不適合我 –