核心数据:fetchResultsController 中的 NSPredicate 是不是可以为每一行返回多个对象,进入我的表视图?

Posted

技术标签:

【中文标题】核心数据:fetchResultsController 中的 NSPredicate 是不是可以为每一行返回多个对象,进入我的表视图?【英文标题】:Core Data: Can a NSPredicate in fetchResultsController return multiple objects for each row, into my Table View?核心数据:fetchResultsController 中的 NSPredicate 是否可以为每一行返回多个对象,进入我的表视图? 【发布时间】:2013-07-25 16:42:46 【问题描述】:

fetchedResultsController 能否返回一个数组数组?还是一个 NSSet 数组?

下面的代码是我正在尝试做的一个示例。有可能吗?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    //...
    NSSet *objects = [_fetchedResultsController objectAtIndexPath:indexPath];
    //...

我这样做的原因是:如果用户滑动单元格并将其删除。我需要删除该行中的所有对象。而且我还需要在该单元格上显示数据,根据该天/行的所有时钟进行的计算。

这是我的核心数据模型:

每一行必须包含给定日期的所有 Clock 对象,具体取决于它的 clockIn 属性。 clockIn 是一个 NSDate 对象。一行应该代表一天。

我可以帮我找出一个谓词吗?有没有可能?

另外,我已经在我的表格视图中使用了部分。所以这些都不在话下。 有一个我宁愿不使用的解决方案,那就是创建年、月和日,实体。这将解决。但我需要这样做似乎很奇怪,考虑到我的 clockIn 属性应该给我我需要的一切。

【问题讨论】:

有什么理由你不能只做Work *work = [_fetchResultsController objectAtIndexPath:indexPath]; NSSet *clocks = work.clock吗? (您还可以通过预取关系将选项传递给 NSFetchedResultsController 以加快速度。) 嗨! Work *work = [_fetchRe... 将只返回 1 行。我需要某一天的所有时钟,这样一排只有一天。换句话说:一行包含某一天的所有时钟。这必须基于时钟的clockIn属性。 您的提取请求是什么样的? entityForName:@"Clock"predicateWithFormat:@"work == %@", self.work 不幸的是,这会为每个时钟返回 1 行。我也认为我可能会在这里找到答案:link 意思是我认为我无法解决我正在尝试的方式? 【参考方案1】:

您可以使用 TLIndexPathTools 通过子类化 TLIndexPathControllerNSFetchedResultsController 的替代方法)在几行代码中完成此操作。我没有对此进行测试,但这里是它的样机:

#import <TLIndexPathController.h>
@interface GroupedIndexPathController : TLIndexPathController
@end

#import "GroupedIndexPathController.h"
#import "TLIndexPathSectionInfo.h"
@implementation GroupedIndexPathController

- (void)setDataModel:(TLIndexPathDataModel *)dataModel

    NSMutableArray *items = [[NSMutableArray alloc] initWithCapacity:dataModel.numberOfSections];
    for (TLIndexPathSectionInfo *sectionInfo in dataModel.sections) 
        if (sectionInfo.objects) 
            [items addObject:sectionInfo.objects];
        
    
    TLIndexPathDataModel *groupedDataModel = [[TLIndexPathDataModel alloc] initWithItems:items andSectionNameKeyPath:nil andIdentifierKeyPath:nil];
    [super setDataModel:groupedDataModel];


@end

您要做的是设置索引路径控制器的获取请求,并将sectionNameKeyPath 设置为您要分组的属性。执行获取时,父类将生成一个组织成部分的数据模型。上面的代码覆盖了dataModel 属性设置器,将这些部分映射到分组对象的单个部分中,例如:

分段数据模型

Section 0
    Managed Object 0.0
    Managed Object 0.1
    Managed Object 0.2
Section 1
    Managed Object 1.0
    Managed Object 1.1

分组数据模型

Section 0
    [Managed Object 0.0, Managed Object 0.1, Managed Object 0.2]
    [Managed Object 1.0, Managed Object 1.1]

然后将此分组数据模型传递给 super 的 dataModel 属性设置器。表视图控制器只会看到分组数据模型。分段数据模型将完全在 GroupedIndexPathController 内部。如果获取结果发生变化,GroupedIndexPathController 将通过controller:didUpdateDataModel: 委托方法将更新报告给分组数据模型,TLTableViewController 将自动为您执行批量更新。

TLIndexPathTools 提供了几个示例项目,Core Data example 演示了如何与 Core Data 集成。您只需要提供GroupedIndexPathController 的实例,而不是标准的TLIndexPathController

您提到您的表格使用部分。如果您能详细说明,我可以修改以上内容以满足您的特定要求。

【讨论】:

【参考方案2】:

不,它不能。

如此处所述:NSPredicate something equivalent of SQL's GROUP BY

“CoreData 是一个对象图管理框架,而不是 SQL 数据存储。因此,您应该尽快摆脱 SQL 思维模式。”

关于手头的问题:

“NSPredicate 旨在作为对象图中限定对象的谓词(毫不奇怪)。因此,您可以获取与查询匹配的所有对象,但这与对这些结果进行分组不同。如果您想这样做聚合操作,使用键值编码的集合操作符。在底层,Core Data 可以将这些转换为合理的 SQL,但这只是一个实现细节。”

【讨论】:

以上是关于核心数据:fetchResultsController 中的 NSPredicate 是不是可以为每一行返回多个对象,进入我的表视图?的主要内容,如果未能解决你的问题,请参考以下文章

如何添加核心数据属性以用于 FRC sectionName Keypath 值

Swift3 CoreData - fetchResultsController

如何过滤在 Core Data 中有对象的表视图?

CoreData 与 tableView 部分

tableView 为空时如何设置一个 fetchedResultsController 驱动的 tableView 单元格?

使用 Fetch Results Controller 对 Core Data 中的单元格重新排序