使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest
Posted
技术标签:
【中文标题】使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest【英文标题】:Core Data NSFetchRequest within specific object using NSPredicate 【发布时间】:2016-02-23 13:25:03 【问题描述】:我有一个核心数据实体,“实体 1”,它与另一个实体“实体 2”之间存在一对多关系,我们称其为“实体关系”。
我希望能够执行 NSFetchRequest 以与 NSFetchResultsController 一起使用,以返回特定“实体 1”对象的“实体 2”对象列表。
我将“实体 1”作为它自己的变量存储出来,但我似乎找不到设置 NSPredicate 以返回对象的正确方法:
这是我的代码:
NSFetchedResultsController *fetchedEvents;
NSFetchRequest *fetchRequest;
NSError *error = nil;
fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"Entity2 IN self = %@",entity1Object]];
[fetchRequest setSortDescriptors:@[]];// no sort descriptors
fetchedEvents = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
[fetchedEvents performFetch:&error];
if (error)
NSLog(@"Unable to perform fetch.");
NSLog(@"%@, %@", error, error.localizedDescription);
return fetchedEvents;
这会崩溃并出现以下错误:
** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Unable to parse the format string "NSMDEvents IN self = %@"'
我做错了吗?或者这是返回具有关系的实体的错误方法?
【问题讨论】:
【参考方案1】:由于您有entity1Object
和定义的关系,您可以直接从那里检索Entity2
对象
NSSet *entity2Objects = [entity1Object valueForKey:@"entityRelationship"];
不需要额外的提取。
但是,如果您确实需要获取,请定义反向关系并使用具有唯一值的属性。
例如让我们假设entity1
是clubs
和entity2
是他们的members
并且您想要让特定俱乐部的所有成员使用这个谓词:
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Member"];
[NSPredicate predicateWithFormat:@"club.name == %@", currentClub.name];
谓词中的文字club
是反向关系对象。
或者翻译成你的例子
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];
[NSPredicate predicateWithFormat:@"entity1.property == %@", entity1Object.property];
【讨论】:
嗨 Vadian,感谢您的帮助,您肯定为我指明了正确的方向,我最终使用我的回答帖子中的代码使其工作,但如果您认为这种方法似乎不正确,请告诉我. 如果它有效,那很好。检查实体对象或实体的特定属性并不重要。顺便说一句:你的命名Entity<ordinalnumber>
很抽象,不是很具描述性,也很难想象。
是的,我应该在那里使用一些更好的命名约定。感谢您的意见。【参考方案2】:
尝试建议的代码(感谢 vadian)一直导致我的应用程序崩溃,并出现各种关于键不存在等的错误,结果证明这是关系问题。
“Entity2”继承自另一个实体(在 Data Model Inspector 中设置了其父 Entity 字段)“Entity 0”。然而,“Entity1”之间的关系是它自己和“Entity0”而不是“Entity2”之间的关系。
因此,在对核心数据模型“Entity2”进行重构之后,在其自身和“Entity1”之间添加了一个关系(我们称之为“EntityEvents”)。现在使用以下代码,我能够从当前对象中选择特定事件:
NSFetchedResultsController *fetchedEvents;
NSFetchRequest *fetchRequest;
NSError *error = nil;
fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Entity2"];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"EntityEvents == %@",Entity1]];
[fetchRequest setSortDescriptors:@[]];// no sort descriptors
fetchedEvents = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:theManagedObjectContext sectionNameKeyPath:nil cacheName:nil];
[fetchedEvents performFetch:&error];
if (error)
NSLog(@"Unable to perform fetch.");
NSLog(@"%@, %@", error, error.localizedDescription);
return fetchedEvents;
【讨论】:
以上是关于使用 NSPredicate 的特定对象内的核心数据 NSFetchRequest的主要内容,如果未能解决你的问题,请参考以下文章