0

多くの場合、アプリでビュー コントローラーをプッシュし、コア データからオブジェクトを取得して UI を埋める状況が発生します。現在、私は通常、メインスレッドの viewDidLoad でこのフェッチを行っていますが、おそらく別のスレッドでこれを行うより良い方法があると確信しています。

実際にスレッドがここに行く方法である場合、私は客観的 c のスレッドの経験があまりないので、誰かがコード例を見せてくれれば本当に感謝しています。

また、コアデータがスレッドセーフではないことも知っているので、安全のために追加の作業を行う必要がありますか?

4

1 に答える 1

2

おそらく、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...
        }];
    }          
}];
于 2012-04-25T05:14:38.153 に答える