使用NSFetchedResultsController按日期排序(包括nil)

时间:2010-03-26 22:12:18

标签: iphone sorting nsfetchedresultscontroller null

在我的NSFetchedResultsController中,我设置了一个sortDescriptor,它根据我的托管对象的date属性进行排序。我遇到的问题(以及谷歌的其他几个问题)是nil值是在最早的末尾而不是日期谱的最后一个末尾排序的。我希望我的列表最早,更早,现在,更晚,最新,零。据我了解,这种排序是在SQLite的数据库级别完成的,因此我无法构建自己的compare:方法来提供我想要的排序。

我不想在内存中手动排序,因为我不得不放弃NSFetchedResultsController的所有好处。我不能进行复合排序,因为sectionNameKeyPaths与日期范围紧密耦合。我可以编写一个重定向indexPath请求的例程,以便结果控制器中的第0部分映射到tableView的最后一部分,但我担心这会增加很多开销,严重增加了我的代码的复杂性,并且非常,非常容易出错。

我正在考虑的最新想法是将所有无日期映射到NSDate支持的最远的未来日期。我的左脑讨厌这个想法,因为它感觉更像是一个黑客。它还需要一些工作才能实现,因为在我的应用程序中处理日期的方式非常重要。如果没有先检查更好的选项,我不想走这条路。谁能想到更好的解决这个问题的方法呢?

更新

解决此问题的一种可能更好的方法是切换到二进制持久性存储。根据我在文档中读到的内容,使用二进制持久存储在Objective-C中完成排序,因此我可以为日期排序提供自己的比较方法。我对这种方法有两个顾虑。首先,通过迁移到二元商店,我会看到什么样的性能?其次,在应用更新中推出此更改有多难?

2 个答案:

答案 0 :(得分:0)

我不知道是否可以在NSFetchedResultsController中更改nil日期的排序位置。但是,我确实有一个建议,就是你将“无日期”更改为未来时间的“黑客”。具体来说,我将为您的实体创建一个返回修改日期的新瞬态属性。基本上,该属性的自定义getter将检索日期,然后检查它是否为nil。如果是这样,它将返回NSDate支持的最新未来日期。这将允许NSFetchedResultsController以您希望的方式对结果进行排序。

使用瞬态属性是指如何创建使用人姓的第一个字母(即联系人应用程序)的部分的列表。执行此操作的方法描述为here

例如:

// THIS ATTRIBUTE GETTER GOES IN YOUR OBJECT MODEL FOR THE 
// TRANSIENT PROPERTY modifedDate
- (NSDate *) modifiedDate {
  [self willAccessValueForKey:@"date"];
  NSDate * date = [self date];
  if(date == nil)
    date = // Set as furthest future date.
  [self didAccessValueForKey:@"date"];
  return date;

}

答案 1 :(得分:0)

我决定使用“hack”修复程序,因为我不想承担将整个对象图加载到使用二进制存储区附带的内存中的开销。当用户没有设置日期时,我不存储nil,而是存储“noDate”类方法的结果。