问题是我需要修改(更新/创建/删除)从0到10000 NSManagedObject的子类。当然,如果它<= 1000,一切正常。我正在使用此代码:
+ (void)saveDataInBackgroundWithBlock:(void (^)(NSManagedObjectContext *))saveBlock completion:(void (^)(void))completion {
NSManagedObjectContext *tempContext = [self newMergableBackgroundThreadContext];
[tempContext performBlock:^{
if (saveBlock) {
saveBlock(tempContext);
}
if ([tempContext hasChanges]) {
[tempContext saveWithCompletion:completion];
} else {
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
}
}];
}
- (void)saveWithCompletion:(void(^)(void))completion {
[self performBlock:^{
NSError *error = nil;
if ([self save:&error]) {
NSNumber *contextID = [self.userInfo objectForKey:@"contextID"];
if (contextID.integerValue == VKCoreDataManagedObjectContextIDMainThread) {
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
}
[[self class] logContextSaved:self];
if (self.parentContext) {
[self.parentContext saveWithCompletion:completion];
}
} else {
[VKCoreData handleError:error];
dispatch_async(dispatch_get_main_queue(), ^{
if (completion) {
completion();
}
});
}
}];
}
只有在保存主线程上下文时才会触发完成。这个解决方案非常完美,但是
当我从服务器获得超过1000个实体时我希望并行对象处理,导致更新操作花费太多时间(例如,4500更新大约90秒且少于此时间的1/3需要JSON接收过程,所以大约60秒我只是钻NSManagedObjects)。没有CoreData,使用dispatch_group_t将数据划分为子数组并同时在不同的线程中处理它是非常容易的,但是......有人知道如何使用CoreData和NSManagedObjectContexts做类似的事情吗?是否可以使用NSPrivateQueueConcurrencyType(iOS 5样式)使用NSManagedObjectContext而不使用performBlock:?什么是保存和合并约10个上下文的最佳方法?谢谢!
答案 0 :(得分:2)
根据您的描述,您似乎正在抓住稻草来恢复表现。
核心数据文件I / O性能主要由SQLite的单线程特性决定。让多个上下文在同一个商店协调员身上殴打并不会让事情变得更快。
要提高性能,您需要采取不同的方式。例如,您可以将后台写入批处理为更大的操作。 (如何?在保存之前,您需要在每个GCD块中执行更多操作。)您可以使用Core Data的调试工具来查看提取和保存所发出的SQL类型。 (有很多方法可以提高CD提取性能,减少提高保存的时间。)
答案 1 :(得分:1)
好的人,在我完成所有实现后,我发现了以下内容:
dispatch_group_t具有不同的PrivateQueues和NSManagedObjectContexts结果:
格式是“实体数/秒”:
单个后台线程(NSManagedObjectContext + NSPrivateQueueConcurrencyType + performBlock:)
所以想想我不应该再试一次,还有很多其他的问题,比如应用程序冻结,同时合并大量的上下文(即使在后台)。我会尝试其他方法来提高性能。
答案 2 :(得分:0)
您可以创建多个上下文并在每个上下文中处理一部分数据......?