当第一个描述符是 NSDate 时,多个 NSSortDescriptor 不起作用

Posted

技术标签:

【中文标题】当第一个描述符是 NSDate 时,多个 NSSortDescriptor 不起作用【英文标题】:Multiple NSSortDescriptor Not Working When The 1st Descriptor is NSDate 【发布时间】:2012-08-15 09:55:00 【问题描述】:

我正在尝试按“recordDate”将数据分成多个部分,然后对于每个部分,数据将按“elementName”升序排序。以下是当前代码(不工作):

NSManagedObjectContext *context = self.tankDatabase.managedObjectContext;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Log"];
request.sortDescriptors = [NSArray arrayWithObjects:[NSSortDescriptor sortDescriptorWithKey:@"recordDate" ascending:NO], [NSSortDescriptor sortDescriptorWithKey:@"elementName" ascending:YES selector:@selector(localizedStandardCompare:)], nil];
request.predicate = [NSPredicate predicateWithFormat:@"ownedBy = %@", self.tank];


self.controller = [[NSFetchedResultsController alloc]
                                          initWithFetchRequest:request
                                          managedObjectContext:context
                                          sectionNameKeyPath:@"recordDate"
                                          cacheName:nil];

self.controller.delegate = self;

NSError *error;
BOOL success = [self.controller performFetch:&error];

但是,当我尝试使用其他属性进行排序(例如:elementName ASC、值 DESC 并按 elementName 对它们进行分组)时,它确实可以正常工作。请注意,recordDate 在数据模型中是“日期”类型,在类中是 NSDate。

recordDate 还包含需要将其分组到该详细信息的分钟和秒。

我尝试在整个互联网上搜索类似案例,但没有找到任何可行的解决方案。我的代码中缺少什么?或者它只是一个苹果的错误?感谢您的时间和帮助。

【问题讨论】:

如果从第二个排序描述符中删除选择器会发生什么? CoreData 对数据库中的事物进行排序,因此您不能拥有使用自定义选择器或比较器的排序描述符。 如果我删除选择器,什么都没有改变。 【参考方案1】:

我终于明白了:

显然,亚秒级信息也被保存到 Core Data 中,使得日期之间的比较(即使被比较的日期共享完全相同的日期)不起作用。

所以我所做的是在将亚秒信息保存到 Core Data 之前删除它:

self.recordDate = [NSDate dateWithTimeIntervalSinceReferenceDate:floor([recordDate timeIntervalSinceReferenceDate])];

我希望这可以帮助任何面临同样问题的人。干杯!

【讨论】:

【参考方案2】:

是的,如果您希望您的子排序描述符(基于 elementName)启动,那么您需要与 recordDate 建立一些联系,因此您截断 recordDate 的想法很好。事实上,很多时候,NSDate 信息被截断为 YY:MM:DD,因此属于同一天的所有事件都无法区分。

顺便说一句,通常只有你的 sectionNameKeyPath 需要“粗粒度”,例如,你通过从 recordDate 中删除亚秒信息来创建一个新的瞬态属性,并将其作为 sectionNameKeyPath 提供给 NSFetchedResultsController。换句话说,您可以按原样继续使用 recordDate...

这类似于姓氏排序(比如升序),其中部分名称为 A、B、C、...、Z。

【讨论】:

以上是关于当第一个描述符是 NSDate 时,多个 NSSortDescriptor 不起作用的主要内容,如果未能解决你的问题,请参考以下文章

当第二个被触摸时,android的状态栏中出现多个推送通知其他人消失

同时生成 NSDate 导致不同的时间间隔

从 [NSDateComponents components: fromDate: toDate: options:] 释放 NSdate 时出错

Javascript regexp - 仅当第一个字符不是星号时

将获取的结果 NSDate 分成每天使用核心数据的部分

WPF:当第二列内容折叠时,DataGrid 不会扩展以占据 Grid 的两列