NSFetchedResultsController 每 4 小时分组一次

Posted

技术标签:

【中文标题】NSFetchedResultsController 每 4 小时分组一次【英文标题】:NSFetchedResultsController group into sections for every 4 hours 【发布时间】:2013-12-15 20:57:09 【问题描述】:

我正在尝试将一系列 NSManagedObjects 分组。每个部分代表一天内的 4 个小时。

- (NSString *)sectionIdentifier

    // Create and cache the section identifier on demand.

    [self willAccessValueForKey:@"sectionIdentifier"];
    NSString *tmp = [self primitiveSectionIdentifier];
    [self didAccessValueForKey:@"sectionIdentifier"];

    if (!tmp)
    
        NSCalendar *calendar = [NSCalendar currentCalendar];
        NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit) fromDate:[self created]];
        tmp = [NSString stringWithFormat:@"%.0f %d %d %d", round(components.hour % 4), components.day, components.month, components.year];
        [self setPrimitiveSectionIdentifier:tmp];
    
    return tmp;

在上面的代码中,在 NSManagedObject 中找到,瞬态属性sectionIdentifier 返回一个字符串,其中包含它所在的时间段(4 小时)、它的创建日期、月份和年份。

但是,虽然 NSFetchedResultController 的 fetchRequest 的排序描述符设置为按照创建日期的顺序对结果进行排序(最新的对象在底部,最旧的在顶部),但由于没有指定部分标识符,因此获取请求失败正确订购。

- (NSFetchedResultsController *) fetchedResultsController 
    if (!_fetchedResultsController) 
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        [fetchRequest setEntity:[NSEntityDescription entityForName:@"PSSpace" inManagedObjectContext:self.managedObjectContext]];
        [fetchRequest setSortDescriptors:@[[NSSortDescriptor sortDescriptorWithKey:@"created" ascending:YES]]];
        _fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"sectionIdentifier" cacheName:nil];
        [_fetchedResultsController setDelegate:self];
    
    return _fetchedResultsController;

CoreData: 错误: (NSFetchedResultsController) 在索引 10 处获取的对象的节名乱序为“1 14 12 2013。对象必须按节名排序”

请您告诉我如何解决订购问题?

谢谢。

【问题讨论】:

【参考方案1】:

试试类似的东西

if (!tmp) 
    NSCalendar *calendar = [NSCalendar currentCalendar];

    NSDateComponents *components = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit) fromDate:[self created]];

    NSUInteger _y = (components.year * 1000000);
    NSUInteger _m = (components.month * 10000);
    NSUInteger _d = (components.day * 100);
    NSUInteger _h = round(components.hour / 4);

    NSUInteger token = (_y + _m + _d + _h);

    tmp = [NSString stringWithFormat:@"%lu", token];

    [self setPrimitiveSectionIdentifier:tmp];

【讨论】:

这实际上与我目前正在做的事情相同。问题在于我正在计算日期所在的 4 周期。我需要用其他东西替换 components.hour % 4 来计算周期。 @max_:不一样。这段代码(几乎)产生一个“YYYYMMDDHH”形式的sectionIdentifier,它产生一个与第一个排序描述符“created”兼容的相对排序。仍有待解决的问题(在我看来):使用固定格式,hour/4 而不是hour % 4 @MartinR 修复了它,早一点意识到我使用了错误的运算符。感谢您花时间看q!如果您愿意,请将其添加为答案,我会接受。 @max_:farski 几乎是正确的。我建议他修复最后的部分,然后你可以接受。 我修好了操作员。可能还有其他更正,仅确保月、日和小时填充 0 可能更有效,这样您就可以格式化字符串而不是对乘法做任何事情。

以上是关于NSFetchedResultsController 每 4 小时分组一次的主要内容,如果未能解决你的问题,请参考以下文章

在 Core Data 应用程序中调用 performFetch 后,是不是需要手动更新表视图?