5

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

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

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

4

3 回答 3

13

要使用获取的结果控制器显示给定对象的相关对象,您将在谓词中使用反向关系。例如:

在此处输入图像描述

要显示与给定父级相关的子级,请使用具有以下获取请求的获取结果控制器:

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

对于嵌套关系,只需按倒序使用逆关系。例子:

在此处输入图像描述

要显示给定国家的街道:

Country *theCountry = ...;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Street"];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = %@", theCountry];
[request setPredicate:predicate];
于 2013-09-01T18:19:54.427 回答
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这变得越来越复杂:我需要检查我的逆关系是否是一对多并使用不同的谓词。我更新了上面的代码示例。

于 2013-09-01T19:09:55.340 回答
-2
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = '%@'", theCountry];

您错过了 predicateWithFormat 字符串中的 ' '。现在它起作用了。

于 2014-07-04T17:47:15.713 回答