Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/iphone/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Iphone 使用NSFetchedResultsController按日期(包括零)排序_Iphone_Sorting_Nsfetchedresultscontroller_Null - Fatal编程技术网

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

Iphone 使用NSFetchedResultsController按日期(包括零)排序,iphone,sorting,nsfetchedresultscontroller,null,Iphone,Sorting,Nsfetchedresultscontroller,Null,在我的NSFetchedResultsController中,我设置了一个sortDescriptor,它根据托管对象的date属性进行排序。我遇到的问题(根据谷歌的说法还有其他几个问题)是,nil值是在日期范围的最早端排序的,而不是在最晚端排序的。我希望我的列表被排序为最早、较早、现在、较晚、最新、零。据我所知,这种排序是在SQLite的数据库级别完成的,因此我无法构造自己的compare:method来提供我想要的排序 我不想在内存中手动排序,因为我将不得不放弃NSFetchedResult

在我的NSFetchedResultsController中,我设置了一个sortDescriptor,它根据托管对象的date属性进行排序。我遇到的问题(根据谷歌的说法还有其他几个问题)是,nil值是在日期范围的最早端排序的,而不是在最晚端排序的。我希望我的列表被排序为最早、较早、现在、较晚、最新、零。据我所知,这种排序是在SQLite的数据库级别完成的,因此我无法构造自己的compare:method来提供我想要的排序

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

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

更新


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

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

“使用瞬态属性”是如何创建带有使用姓氏第一个字母的部分的列表(联系人应用程序中的la)。描述了一种实现该目的的方法

例如:

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

}

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

“使用瞬态属性”是如何创建带有使用姓氏第一个字母的部分的列表(联系人应用程序中的la)。描述了一种实现该目的的方法

例如:

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

}

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

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

据我所知,sectionNameKeyPath可以使用transient属性(事实上,我使用transient属性)但不能用于排序描述符,因为排序是由SQLite在数据库级别完成的,并且该瞬态属性在数据库中不存在。如果我误解了这一点,请随时纠正我。另一方面,我将使用transient属性“解释”hack日期,并在遇到特定日期时返回nil。这将防止我不得不在代码的其他部分处理假日期。我的错误。您认为暂时属性不能用作排序描述符是正确的。如果必须在数据库中进行排序,则可以将hasDate布尔属性添加到对象模型中,并首先按该属性排序,然后按日期排序。然而,除了向数据库添加冗余之外,我还假设这是您在原始问题中希望避免的“复合排序”方法。是的,这就是我所说的复合排序。sectionNameKeyPath必须匹配fetch请求中第一个排序描述符的排序顺序,因此按hasDate first排序在tableView中最多只能得到两个部分。据我所知,sectionNameKeyPath可以使用瞬态属性(事实上,我使用瞬态属性)但不能用于排序描述符,因为排序是由SQLite在数据库级别完成的,并且该瞬态属性在数据库中不存在。如果我误解了这一点,请随时纠正我。另一方面,我将使用transient属性“解释”hack日期,并在遇到特定日期时返回nil。这将阻止我在其他PAR中处理假日期。