4

我有一个带有属性“日期”的核心数据类“会议”,我想使用 NSFetchedResultsController 在 TableView 中显示它。会议应按两种方式排序:首先,应将一个月的所有会议汇总在同一部分中,然后将一个月/部分中的所有会议按日期排序。

    NSComparisonResult (^periodSortBlock)(id, id) = ^(id obj1, id obj2) {                
        NSLog(@"Debug");            

        NSDate *date1 = (NSDate *)obj1;
        NSDate *date2 = (NSDate *)obj2;

        // Pseudocode
        Month *month = [Month monthWithDate:date1];
        NSComparisonResult result = NSOrderedSame;

        if ([Month date:date2 afterDate:month.end])
            result = NSOrderedAscending;
        else if ([Month date:date2 beforeDate:month.start])
            result = NSOrderedDescending;

        return result;
    };        

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Meeting"];        
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", self.meetings];

    NSSortDescriptor *sectionByMonth = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:false comparator:periodSortBlock];
    NSSortDescriptor *sortByDate = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:false];

    fetchRequest.sortDescriptors = [NSArray arrayWithObjects:sectionByMonth, sortByDate, nil];

    frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"date" cacheName:nil];
    [frc performFetch:nil];

代码编译没有任何错误,但排序没有按预期工作:每个会议都有自己的部分。

据我所见,排序块被完全忽略且未被调用: NSLog 语句不会产生任何输出,并且块内的断点不会停止执行。

代替 sortDescriptorWithKey:ascending:comarator: 我可以使用 sortDescriptorWithKey:ascending:。结果是完全一样的。

如果块直接在 sortDescriptorWithKey:ascending:comparator: 语句中声明或作为变量(如上)也没有任何区别。

将块定义为 (NSDate*, NSDate*) 而不是 (id, id) 也没有区别。

这里出了什么问题?我会理解块内的排序是否会产生一些错误。但是它没有调用的块怎么可能呢?

4

1 回答 1

6

感谢保罗的提示,我能够找出问题所在。该解决方案可以在Apple 文档中找到(查看“获取谓词和排序描述符”部分)。

我认为 NSFetchRequest 只会使用 SQL 从 SQLite DB 中获取对象,然后使用 SortDiscriptors 对内存中获取的对象进行排序。这不是真的:似乎完整的排序工作也交给了 SQLite 存储。当然,来自块的 Obective-C 语句不能被翻译成 SQL 查询,因此该块被忽略。

于 2012-06-14T10:23:31.087 回答