核心数据在后台线程上缓慢处理更新
Posted
技术标签:
【中文标题】核心数据在后台线程上缓慢处理更新【英文标题】:Core data slow processing updates on a background thread 【发布时间】:2016-03-03 00:25:22 【问题描述】:在后台线程上处理更新时,我的应用程序速度存在重大问题。 Instruments 显示,几乎所有这些时间都花在了 performBlockAndWait
内,我在那里提取需要更新的对象。
根据离线时间的长短,我的更新可能会成百上千次,而我目前使用的方法是单独处理它们;即获取请求以提取对象,更新,然后保存。
听起来很慢,确实如此。我遇到的问题是我不想一次将所有内容加载到内存中,因此需要在进行时单独获取它们,并且我会在进行时保存以确保如果单个更新出现问题,它将不会别搞砸了。
有更好的方法吗?
【问题讨论】:
【参考方案1】:在插入大量对象时,我遇到了类似的缓慢性能。就我而言,我愿意将完整的更改集保留在内存中并执行一次保存,因此大量的获取请求占据了我的处理时间。
通过维护内存缓存将我的资源主键映射到NSManagedObjectID
s,我获得了显着的性能提升。这让我可以使用 existingObjectWithId:error:
而不是对单个对象的获取请求。
我怀疑我可能会做得更好,方法是收集给定实体描述的所有资源的主键,一次为所有资源发出单个提取请求(根据需要批量处理这些结果),然后处理对每个资源的更改资源。
【讨论】:
【参考方案2】:假设您只针对 ios 8+,您可能会从使用 NSBatchUpdateRequest
中受益。
These guys have a great example of it 但 TLDR 基本上是:
示例:假设我们要更新 MyObject 的所有未读实例以标记为已读:
NSBatchUpdateRequest *req = [[NSBatchUpdateRequest alloc] initWithEntityName:@"MyObject"];
req.predicate = [NSPredicate predicateWithFormat:@"read == %@", @(NO)];
req.propertiesToUpdate = @
@"read" : @(YES)
;
req.resultType = NSUpdatedObjectsCountResultType;
NSBatchUpdateResult *res = (NSBatchUpdateResult *)[context executeRequest:req error:nil];
NSLog(@"%@ objects updated", res.result);
注意上面的例子取自前面的博客,sn-p不是我写的。
【讨论】:
这些更新无论如何都没有关系,所以我不知道如何批量处理它们。 啊,我明白了。没有从原始问题中收集到它们是不相关的更新。那么你可能会不走运,除非你可以将它们分批。例如,假设您有 A、B 和 C 类型的更新,您可以将它们单独排队,然后定期对所有 A 进行批量更新,对所有 B 进行批量更新等。以上是关于核心数据在后台线程上缓慢处理更新的主要内容,如果未能解决你的问题,请参考以下文章
核心数据-后台线程中的更新实体会自动更改主线程中的 NSManagedObject 而无需合并-为啥?