NSSortDescriptor未应用于iOS 5.1下的获取请求结果(但在iOS 6+下工作正常)

时间:2013-09-26 23:54:08

标签: ios nsfetchrequest nssortdescriptor

我有一个获取请求“foo”,我有一个排序描述符(它按降序排序Integer 16属性)。我这样执行获取请求:

__block NSArray *results = nil;

[_managedObjectContext performBlockAndWait:
 ^{
     results = [_managedObjectContext executeFetchRequest:<foo> error:nil];
 }];

return results;

当我在iOS 6+下执行此获取请求时,结果按指定/预期排序(反向整数索引顺序)。

但是,当我在iOS 5.1下执行它时,结果是未分类的!

但是如果我然后立即将完全相同的排序描述符应用于结果数组:

results = [results sortedArrayUsingDescriptors:<foo>.sortDescriptors];

然后正确排序结果。

还有其他人遇到过这样的事吗?如果是的话,你找到了原因吗?

谢谢!

卡尔

P.S。:如果证明相关,这里是“foo”的定义:

-(NSFetchRequest *)fetchRequestForUnparsedStoriesOfStoryListWithId:(id)storyListId
{
    NSPredicate *hasStoryListWithIdPredicate = [NSPredicate predicateWithFormat:@"ANY lists.id = %@", storyListId];
    NSPredicate *isUnparsedStoryOfStoryListWithIdPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:@[hasStoryListWithIdPredicate, self.isUnparsedPredicate]];

    NSFetchRequest *fetchRequestForUnparsedStoriesOfStoryListWithId = [NSFetchRequest fetchRequestWithEntityName:@"Story"];
    fetchRequestForUnparsedStoriesOfStoryListWithId.predicate = isUnparsedStoryOfStoryListWithIdPredicate;
    fetchRequestForUnparsedStoriesOfStoryListWithId.sortDescriptors = [NSArray arrayWithObject:self.descendingIndexSortDescriptor];

    return fetchRequestForUnparsedStoriesOfStoryListWithId;
}

以下是排序描述符的定义:

-(NSSortDescriptor *)descendingIndexSortDescriptor
{
    if (! _descendingIndexSortDescriptor)
    {
        self.descendingIndexSortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"index" ascending:NO];
    }

    return _descendingIndexSortDescriptor;
}

PPS:更多上下文,以及此获取的上下文:这是在应用程序启动时发生的,1)后台线程/后台-MOC(具有NSPrivateQueueConcurrencyType的嵌套MOC)解析服务器信息已确定一些基本属性,然后2)在后台MOC中创建了一组Story实体,其中(尤其)索引被排序,然后3)将更改保存在该背景MOC上。在这些操作完成之后,立即执行上述获取请求,并且在相同的后台线程和后台MOC上执行。在这里阅读:NSSortdescriptor ineffective on fetch result from NSManagedContext - “除非数据一直保存回Persistent Store,否则如果主上下文中的数据是脏的,即修改后,排序将不起作用”,我试图强制保存在步骤3))所有方式“嵌套”嵌套的MOC链到持久存储(即,到磁盘),但这也没有影响:在iOS 5.1(仅)下,此提取的结果未排序,除非我排序执行提取后“手动”结果。

2 个答案:

答案 0 :(得分:1)

好的,经过进一步的实验,我确定,确实,iOS 5.1中的 (但不是iOS 6+),如下所述:NSSortdescriptor ineffective on fetch result from NSManagedContext - “除非数据是一直保存回持久存储,如果主上下文中的数据是脏的,即修改后,排序将不起作用。如果我在执行获取请求之前将所有实体更改(插入,修改,删除)保存到持久性存储(在嵌套MOC链中一直执行同步保存到磁盘-MOC),则会对结果进行正确排序。如果我不这样做,结果不会排序。

所以:如果您的应用程序需要在iOS 5.1下运行,并且您使用嵌套的MOC,则必须1)在执行已排序的提取请求之前将所有方式“向上”保存到持久性存储(例如磁盘),或者2)自己对取得的结果数组进行排序。

(即使这个问题实际上已经在链接的帖子中得到解答,我将留下这个问题并在这里回答,直到/除非要求删除它,因为我认为它更清楚,更明确问题及其解决方案是什么。)

答案 1 :(得分:0)

  1. 您可能不希望以这种方式使用performBlockAndWait。它仅用于重入,因此它无法执行performBlock为您所做的一些事情 - 如自动释放池和用户事件。用户事件对于核心数据按预期运行非常重要。例如,在performBlockAndWait内进行的更改不会触发NSManagedObjectContext通知!有关详细信息,请参阅iOS 5 Core Data release notes

  2. iOS 5.x上的CoreData存在许多已知问题,这些问题已在iOS 6上修复。要列出的内容太多。如果父上下文中有更改,那么排序将无法正常工作,我确实认为还有另一个关于排序的问题。不幸的是,我不再拥有雷达数字。

  3. 如果使用带有信号量的performBlock代替performBlockAndWait,您是否会遇到相同的排序问题,如WWDC 2012会话214“核心数据最佳实践”中所示?