2013-09-01 127 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

这不适合我 –