NSManagedObjectContext performBlock和dispatch_group_t

时间:2012-12-17 03:02:14

标签: ios5 core-data grand-central-dispatch nsmanagedobjectcontext

问题是我需要修改(更新/创建/删除)从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个上下文的最佳方法?谢谢!

3 个答案:

答案 0 :(得分:2)

根据您的描述,您似乎正在抓住稻草来恢复表现。

核心数据文件I / O性能主要由SQLite的单线程特性决定。让多个上下文在同一个商店协调员身上殴打并不会让事情变得更快。

要提高性能,您需要采取不同的方式。例如,您可以将后台写入批处理为更大的操作。 (如何?在保存之前,您需要在每个GCD块中执行更多操作。)您可以使用Core Data的调试工具来查看提取和保存所发出的SQL类型。 (有很多方法可以提高CD提取性能,减少提高保存的时间。)

答案 1 :(得分:1)

好的人,在我完成所有实现后,我发现了以下内容:

dispatch_group_t具有不同的PrivateQueues和NSManagedObjectContexts结果:

格式是“实体数/秒”:

  • 333/6
  • 1447/27
  • 77分之3982

单个后台线程(NSManagedObjectContext + NSPrivateQueueConcurrencyType + performBlock:)

  • 333/1
  • 1447/8
  • 47分之3982

所以想想我不应该再试一次,还有很多其他的问题,比如应用程序冻结,同时合并大量的上下文(即使在后台)。我会尝试其他方法来提高性能。

答案 2 :(得分:0)

您可以创建多个上下文并在每个上下文中处理一部分数据......?

相关问题