我正在使用一个非常复杂的对象模型,并且在将我的一些提取分解为多个部分以在表格 View 中显示时遇到了一些麻烦。
我需要将 Meeting
托管对象分组到几个不同的“口袋”中,例如项目、客户和其他一些。出于几个原因,我决定将这些实现为可以与 session 实体关联的标签。
所以我创建了一个新的 Tag
实体,它有一个类型和一个值,并建立了两者之间的关系:
Meeting <<-->> Tag
如果我想将 session 与项目相关联,我创建一个名称为“项目”且值为“项目名称”的标签,然后通过关系将其添加到 session 实体。
我最初考虑使用 NSFetchedResultsController,但我遇到了各种各样的问题,所有这些我都不太了解。
例如,这个提取(我省略了不必要的位):
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[Meeting entityName] inManagedObjectContext:moc];
NSPredicate *predicate = [NSPredicate predicateWithFormat"tags.name contains[] 'client'"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey"title" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[fetch setEntity:entity];
[fetch setPredicate:predicate];
[fetch setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch
managedObjectContext:moc
sectionNameKeyPath"self.tags.value"
cacheName:nil];
在这种特殊情况下,获取确实有效,但不知何故,我得到了意想不到的结果,其中不仅显示了具有值 client
的 Tags
,而且还显示了具有值 project 的
???Tags
如果我将谓词更改为 tags.name == 'project'
我会得到一个异常:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'to-many key not allowed here'
我可能在这里遗漏了一些基本的东西,而且我承认我在谓词方面没有很多经验,但 Apple 关于该主题的文档还有很多不足之处。
作为一个附带问题,我也不明白为什么我必须在 self.tags.value
中将 self
添加到我的 sectionNameKeyPath 中?它有什么作用??在这种情况下,如果我不添加它,我也会抛出异常:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid to many relationship in setPropertiesToFetch: (tags.value)
最后,在这种情况下,使用 fetched results controller 的替代方法是什么?它会是一堆获取请求,我首先获取 Tag
的每个实例,其中 name == 'project'
并遍历数组以提取与其关联的 session 对象吗?这似乎效率很低,但目前我能想到的只有这些,所以如果您有任何其他想法,我很想听听。
非常感谢您抽出宝贵的时间,
罗格
问题是 Meeting
有很多 tags
,所以你需要使用聚合操作:
NSFetchRequest *fetch = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:[Meeting entityName] inManagedObjectContext:moc];
NSPredicate *predicate = [NSPredicate predicateWithFormat"ANY tags.name contains[cd] 'client'"];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey"title" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];
[fetch setEntity:entity];
[fetch setPredicate:predicate];
[fetch setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetch
managedObjectContext:moc
sectionNameKeyPath"clientName"
cacheName:nil];
即给我一个所有 Meeting
对象的列表,其中 tags
的 ANY
属于 client
类型,并将它们分组客户名称
。要使 clientName
键路径起作用,您需要实现一个临时属性:
- (NSString *)clientName {
[self willAccessValueForKey"clientName"];
// Set clientName to the value of the first tag with name 'client'
NSString* clientName = @"...";
[self didAccessValueForKey"clientName"];
return clientName;
}
如果您的许多 NSManagedObject
子类需要 clientName
属性,您可以在一个通用抽象 NSManagedObject
子类中实现它,并使您的具体子类从那里继承。
关于ios - Coredata 在部分中获取和分组对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7071278/
欢迎光临 OStack程序员社区-中国程序员成长平台 (https://ostack.cn/) | Powered by Discuz! X3.4 |