我在处理后台线程更新时的应用程序速度方面存在主要问题。仪器显示,几乎所有的时间都在performBlockAndWait
之内,用于获取需要更新的对象。核心数据在后台线程上处理更新缓慢
根据离线时间的长短,我的更新可能会有数百个,我目前使用的方法是单独处理它们;即获取请求来取出对象,更新,然后保存。
它听起来很慢,它是。我遇到的问题是我不想一次性将所有内容加载到内存中,因此需要单独提取它们,并且在保存时保存,以确保如果单次更新时出现问题,把其余的东西弄糟。
有没有更好的方法?
我在处理后台线程更新时的应用程序速度方面存在主要问题。仪器显示,几乎所有的时间都在performBlockAndWait
之内,用于获取需要更新的对象。核心数据在后台线程上处理更新缓慢
根据离线时间的长短,我的更新可能会有数百个,我目前使用的方法是单独处理它们;即获取请求来取出对象,更新,然后保存。
它听起来很慢,它是。我遇到的问题是我不想一次性将所有内容加载到内存中,因此需要单独提取它们,并且在保存时保存,以确保如果单次更新时出现问题,把其余的东西弄糟。
有没有更好的方法?
假设您只针对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);
注意上面的例子是取自前面提到的博客,我没有写这段代码。
当插入大量对象时,我遇到类似的性能下降。在我的情况下,我愿意保留在内存中设置的全部更改,并执行一次保存,以便大量的提取请求支配我的处理时间。
从维护内存缓存映射我的资源的主键到NSManagedObjectID
s,我得到了显着的性能提升。这允许我使用existingObjectWithId:error:
而不是针对单个对象的获取请求。
我怀疑我可能通过收集给定实体描述的所有资源的主键,一次发出一个单一的提取请求(根据需要对这些结果进行批处理),然后将更改处理为每个资源。
这些更新无论如何都没有关联,尽管如此我看不到我如何批量更新。 – trapper
啊,我明白了。没有从最初的问题中收集到他们是无关的更新。你可能会失败,除非你可以批量分组。例如,假设你有类型A,B和C的更新,你可以将它们单独排队,然后定期对所有A进行批量更新,对所有B进行批量更新等。 – mszaro