包含关系中对象的NSFetchedResultsController

时间:2013-09-01 17:21:17

标签: objective-c core-data nspredicate

我有NSManagedObject个相关对象。关系由keyPath描述。

现在我想在表格视图中显示这些相关对象。当然,我可以将这些对象的NSSet作为数据源,但我更愿意使用NSFetchedResultsController重新获取对象,以便从其功能中受益。

如何创建描述这些对象的谓词?

3 个答案:

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

答案 1 :(得分: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 这变得越来越复杂:我需要检查我的反向关系,如果它是to-many并使用不同的谓词。我更新了上面的代码示例。

答案 2 :(得分:-2)

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

你在missateWithFormat字符串中错过了''。现在它起作用了。