我有NSManagedObject
个相关对象。关系由keyPath描述。
现在我想在表格视图中显示这些相关对象。当然,我可以将这些对象的NSSet
作为数据源,但我更愿意使用NSFetchedResultsController
重新获取对象,以便从其功能中受益。
如何创建描述这些对象的谓词?
答案 0 :(得分: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];
答案 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字符串中错过了''。现在它起作用了。