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: なしで NSPrivateQueueConcurrencyType (iOS 5 スタイル) で NSManagedObjectContext を操作することは可能ですか? また、約 10 個のコンテキストを保存してマージする最良の方法は何ですか? ありがとう!

4

3 に答える 3

2

あなたの説明によると、パフォーマンスを回復するためにストローをつかんでいるようです。

コア データ ファイルの I/O パフォーマンスは、SQLite のシングル スレッドの性質によって支配されます。複数のコンテキストが同じストア コーディネーターを打ち負かしても、物事が速く進むわけではありません。

パフォーマンスを向上させるには、さまざまなことを行う必要があります。たとえば、バックグラウンド書き込みをより大きな操作にバッチ処理できます。(どのように? 保存する前に、各 GCD ブロックでさらに多くのことを行う必要があります。) Core Data のデバッグ ツールを使用して、フェッチと保存によって発行されている SQL の種類を確認できます。(CD フェッチのパフォーマンスを改善する方法はたくさんありますが、保存を改善する方法はほとんどありません。)

于 2012-12-17T13:16:48.463 に答える
1

わかりました、私が望むすべてを実装し終えた後、私は次のことを発見しました:

異なる PrivateQueues と NSManagedObjectContexts の結果を持つ dispatch_group_t:

形式は「エンティティ数/秒」です。

  • 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 に答える