我有一个Core Data类“Meeting”,其属性为“date”,我希望使用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:升序:比较器:我可以使用sortDescriptorWithKey:ascending:。结果完全一样。
如果块直接在sortDescriptorWithKey中声明:ascending:comparator:语句或作为变量(如上所述)也没有任何区别。
将块定义为(NSDate *,NSDate *)而不是(id,id)也没有区别。
这里出了什么问题?我会理解块内的排序是否会产生一些错误。但它怎么可能没有调用它?
答案 0 :(得分:6)
感谢Paul的提示,我能够弄清楚问题是什么。解决方案可以在Apple docs中找到(查看“获取谓词和排序描述符”部分)。
我认为NSFetchRequest只会使用SQL从SQLite DB中获取对象,然后使用SortDiscriptors对内存中的已获取对象进行排序。事实并非如此:似乎完整的排序工作也会移交给SQLite存储。当然,块的Obective-C语句不能转换为SQL查询,因此忽略该块。