1

问题是我需要修改(更新/创建/删除)从 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 制作类似的东西吗?是否可以在没有 performBlock: 的情况下使用 NSManagedObjectContext 和 NSPrivateQueueConcurrencyType(iOS 5 风格)?保存和合并大约 10 个上下文的最佳方法是什么?谢谢!

4

3 回答 3

2

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

Core Data 文件 I/O 性能主要由 SQLite 的单线程特性决定。有多个上下文在同一个商店协调器上跳动不会让事情进展得更快。

为了提高性能,您需要以不同的方式做事。例如,您可以将后台写入批处理到更大的操作中。(怎么做?你需要在保存之前在每个 GCD 块中做更多的事情。)你可以使用 Core Data 的调试工具来查看你的获取和保存发出了什么样的 SQL。(有很多方法可以提高 CD 获取性能,但很少有提高节省的方法。)

于 2012-12-17T13:16:48.463 回答
1

好的,在我完成我想要的一切后,我发现了以下内容:

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

格式是“实体数/秒”:

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

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

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

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

于 2012-12-17T16:50:28.137 回答
0

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

于 2012-12-17T09:33:05.437 回答