OStack程序员社区-中国程序员成长平台

标题: ios - Coredata 在部分中获取和分组对象 [打印本页]

作者: 菜鸟教程小白    时间: 2022-12-12 17:06
标题: ios - Coredata 在部分中获取和分组对象

我正在使用一个非常复杂的对象模型,并且在将我的一些提取分解为多个部分以在表格 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];

在这种特殊情况下,获取确实有效,但不知何故,我得到了意想不到的结果,其中不仅显示了具有值 clientTags,而且还显示了具有值 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 对象吗?这似乎效率很低,但目前我能想到的只有这些,所以如果您有任何其他想法,我很想听听。

非常感谢您抽出宝贵的时间,

罗格



Best Answer-推荐答案


问题是 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 对象的列表,其中 tagsANY 属于 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