核心数据:后台获取,NSFetchedResultsController和排序时间

|| 我遇到的问题如下: 我有一个“ 0”,我从“ 1”中获取数据,而“ 1”从核心数据中检索了大约6000行。
NSFetchRequest
中的
fetchBatchSize
设置为20,如果我不应用任何
NSSortDescriptor
,则抓取速度足够快,不会阻塞UI线程。 但是,我确实需要显示那些使用以下NSSortDescriptor按字母顺序排序的行:
[[[NSSortDescriptor alloc] initWithKey:@\"optionText\" ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];
当事情发生变化时,由于正在对6000行进行排序,因此提取操作现在大约需要3秒钟才能完成。显然,在那几秒钟中,UI被阻止,用户体验非常糟糕。 我知道我可以在后台线程中进行提取,然后将对象ID传递给主线程,但是在那种情况下,我如何仍可以在主线程中使用ѭ1(我也使用它来观察数据的变化) )? 我还有[7]我要进行排序的属性,但这只会优化查找,而不优化排序性能。 任何想法将不胜感激,谢谢!     
已邀请:
首先,NSFetchedResultsController通常用于主线程。而且,直到苹果发布iOS 6为止,它都不支持后台获取。 因此,当调用NSFetchedResultController的performFectch时,必须“阻塞”主线程一段时间。但是,我们确实希望时间最少。 (据我所记得,您必须为NSFetchedResultController设置一个排序描述符。因此,我不确定在不设置排序描述符的情况下如何使它工作。请看一下类引用) 我不确定您是否使用Sqlite Store。如果是这样,我几乎无法相信您的排序描述符有效。 (请参阅《核心数据编程指南:故障排除》部分)。如果没有,那么在内存中保留这么多数据将不是一个好主意 终于我们到达了为什么它慢的点。这种使用\“ localizedCaseInsensitiveCompare:\”的排序会使您的读取变慢,因为比较Unicode字符串会变慢。 (在WWDC 2010 iPhone上的核心数据性能中提到)。 与许多其他应用程序一样,您应基于\“ optionText \”创建一个非Unicode字符串字段/属性,并基于该非Unicode字符串属性进行排序。     
如何使用NSFetchRequest的
batchSize
属性?   如果您将批处理大小设置为非零,则返回对象集合   执行提取时将分为几批。当获取   执行后,将评估整个请求并确定所有身份   匹配记录的对象,但不超过batchSize对象的数据   将一次从持久性存储中获取。数组   执行请求返回的将是一个代理对象   按需透明地对批次进行故障处理。 (用数据库术语来说,这是一个   内存中的游标。)     
我在NSOperation中执行后台批处理导入,该操作使用单独的NSManagedObjectContext。我会定期保存第二个上下文,该第二个上下文会触发通知以更新我的主NSManagedContext,并将其连接到我的NSFetchedResultsController。 也许可以将类似的技术应用于您的提取 这是我女友关于可可的文章: http://www.cimgf.com/2011/05/04/core-data-and-threads-without-the-headache/ 核心数据编程指南“分批导入”中也提到了该技​​术 http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/CoreData/Articles/cdImporting.html#//apple_ref/doc/uid/TP40003174-SW1     
使用缓存可能有助于获得更好的性能。 我遇到了同样的问题,并意识到在第一个调用中,提取需要3秒钟以上的时间,但是执行两次提取将立即显示其结果。     
就用户体验而言,在一张表中显示6000行可能不是最佳解决方案。也许您应该在之前添加一个过滤器表。与通讯录中的组类似。如果您设法将每个过滤器的行数减少到更易于管理的数目,则可能会带来更好的用户体验。这将减少加载时间和滚动时间。 我不知道您要显示哪种数据,因此也许只能将所有数据显示在一个长长的列表中。对于人们,您可以添加性别和年龄组的选项。对于汽车,您可以按品牌和型号添加过滤器。...     
您是否尝试过在后台运行performFetch:方法?
[controller performSelectorInBackground:@selector(performFetch) withObject:nil];
要么
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
    [controller performFetch];
});
    

要回复问题请先登录注册