Instruments を使用した後、非常に長時間実行され、UI をブロックしているコード内のスポットを見つけました: 大量のコア データ フェッチ (これは、大きな JSON パケットを取り込み、管理対象オブジェクトを構築するプロセスの一部です。重複していません)。
私の意図は、このリクエストを小さな断片に分割して順次処理することですが、それは単にそれらのフェッチを分散させることを意味します - その効果は、1 回の長いしゃっくりではなく、アプリでの小さなジャーキネスの爆発になると予想しています.
Apple のドキュメントとオンラインのさまざまなブログ投稿の両方で私が読んだすべてのことは、Core Data と同時実行性が蜂の巣を突っついているようなものであることを示しています。それで、私はおずおずと座って、昔ながらの大学で試してみました。以下は私が思いついたものです。私が書いたと確信している誤りを指摘してくれる賢い人に感謝します。
以下に投稿されたコードは機能します。私が読んだことは、私が間違いなく何か間違ったことをしたと脅迫しました。手榴弾からピンを抜いたような気がして、思いがけず爆発するのを待っているだけです!
NSBlockOperation *downloadAllObjectContainers = [NSBlockOperation blockOperationWithBlock:^{
NSArray *containers = [webServiceAPI findAllObjectContainers];
}];
[downloadAllObjectContainers setCompletionBlock:^{
NSManagedObjectContext *backgroundContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[backgroundContext setPersistentStoreCoordinator:[_managedObjectContext persistentStoreCoordinator]];
[[NSNotificationCenter defaultCenter] addObserverForName:NSManagedObjectContextDidSaveNotification
object:backgroundContext
queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *note) {
[_managedObjectContext mergeChangesFromContextDidSaveNotification:note];
}];
Builder *builder = [[Builder alloc] init];
[builder setManagedObjectContext:backgroundContext];
for (ObjectContainer *objCont in containers) { // This is the long running piece, it's roughly O(N^2) yuck!
[builder buildCoreDataObjectsFromContainer:objCont];
}
NSError *backgroundContextSaveError = nil;
if ([backgroundContext hasChanges]) {
[backgroundContext save:&backgroundContextSaveError];
}
}];
NSOperationQueue *background = [[NSOperationQueue alloc] init];
[background addOperation:downloadAllObjectContainers];