如何解决核心数据:后台获取,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];
});
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。