我有一个NSManagedObject
相关的对象。该关系由 keyPath 描述。
现在我想在表格视图中显示这些相关对象。当然,我可以将NSSet
这些对象作为数据源,但我更愿意重新获取对象以NSFetchedResultsController
从其功能中受益。
如何创建描述这些对象的谓词?
我有一个NSManagedObject
相关的对象。该关系由 keyPath 描述。
现在我想在表格视图中显示这些相关对象。当然,我可以将NSSet
这些对象作为数据源,但我更愿意重新获取对象以NSFetchedResultsController
从其功能中受益。
如何创建描述这些对象的谓词?
要使用获取的结果控制器显示给定对象的相关对象,您将在谓词中使用反向关系。例如:
要显示与给定父级相关的子级,请使用具有以下获取请求的获取结果控制器:
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];
谢谢马丁,你给了我重要的信息。
为了一般地获取关键路径,我找到了以下实现:
// 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这变得越来越复杂:我需要检查我的逆关系是否是一对多并使用不同的谓词。我更新了上面的代码示例。
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"city.country = '%@'", theCountry];
您错过了 predicateWithFormat 字符串中的 ' '。现在它起作用了。