2

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

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

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

更新

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

4

2 回答 2

0

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

使用瞬态属性是如何创建包含使用个人姓氏的第一个字母的部分的列表(a la the Contacts App)。此处描述了一种方法。

例如:

// 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;

}

于 2010-03-26T22:56:06.450 回答
0

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

于 2010-04-04T07:37:03.533 回答