おそらく、NSFetchedResultsController を使用する必要があります。バッチ処理を管理し、その時点で必要なものだけをロードします。テーブルビューだけではありません。別のスレッドなしでこれを行うことができます (DB が大きすぎず、フェッチに DB 内のすべてのレコードにアクセスする必要がある複雑な述語がない限り)。
FRC の代わりに、またはすべてのレコードが必要な場合は、別のスレッドを使用してオブジェクトをフェッチし、それらをメイン スレッドに提示できます。
これらは単一の SO 回答で説明するのが難しい概念であるため、それでも意味が分からない場合は、Core Data Concurrency Programming Guide を参照してください。
または、すべてをロードし、ある程度制御したい場合は、次のようにすることができます。注: このデュアル MOC パターンは、バックグラウンド処理が簡単になるため、とにかく進むべき道だと思います。さらに言えば、UIManagedDocument を使用すれば、これらのほとんどをとにかく無料で入手できます。
これにより、ロードに全体的に時間がかかる可能性がありますが、UI スレッドが解放されます。
NSManagedObjectContext *workerMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
workerMoc.persistentStoreCoordinator = psc;
// The "mainMoc" will be a child of the worker
NSManagedObjectContext *mainMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
mainMoc.parentContext = workerMoc;
それから読み込み時...
// The actual work will run in the background on the worker queue
// The "worker" queue will do the fetching and faulting, then pass object IDs
// to the mainMoc, which will fault its MOs from the parent
[workerMoc performBlock:^{
NSFetchRequest *fetchRequest = // Create fetch request
NSArray *fetchResults = [workerMoc executeFetchRequest:fetchRequest error:0];
[fetchResults enumerateObjectsUsingBlock:^(NSManagedObject *obj, NSUInteger idx, BOOL *stop) {
// Probably want to fault the object in before going to mainMoc
// since that can also take some time...
// Can also "batch" them in some small number of objects.
NSManagedObjectID *objectID = obj.objectID;
[mainMoc performBlock:^{
NSManagedObject *fetchedObject = [mainMoc objectWithID:objectID];
// Do something with it now that you are back on the main thread...
}];
}
}];