4

私は Magical Record を初めて使用しますが、stackoverflow に関するいくつかの質問を既に見たことがあり、私の質問に対する答えが見つかりません。

このタイプの構造を使用して、述語を持つアイテムを見つける必要があります。

NSArray *result = [MOSomeItems MR_findAllWithPredicate:predicate];

メイン スレッドで結果が返されますが、UI がフリーズしています。

この構造を使用すると、結果は nil 値を返します。

dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
NSArray *result = [MOSomeItems MR_findAllWithPredicate:predicate];
});

バックグラウンドでデータを取得するためのベスト プラクティスは何ですか?

4

1 に答える 1

16

プライベート キューでコンテキストを使用し、フェッチした ID を使用してメイン コンテキストから結果を引き出す必要があります。

// Create a child context of our main context
NSManagedObjectContext *privateContext = [NSManagedObjectContext MR_context];
// When using private contexts you must execute the core data code in it's private queue using performBlock: or performBlockAndWait:
[privateContext performBlock:^{
  // Execute your fetch
  NSArray *privateObjects = [MOSomeItems MR_findAllWithPredicate:predicate inContext:privateContext];
  // Convert your fetched objects into object IDs which can be pulled out of the main context
  NSArray *privateObjectIDs = [privateObjects valueForKey:@"objectID"];
  // Return to our main thread
  dispatch_async(dispatch_get_main_queue(), ^{
    // Create a new predicate to use to pull our objects out
    NSPredicate *mainPredicate = [NSPredicate predicateWithFormat:@"self IN %@", privateObjectIDs];
    // Execute your fetch
    NSArray *finalResults = [MOSomeItems MR_findAllWithPredicate:mainPredicate];
    // Now you can use finalResults however you need from the main thread
  });
}];

-[NSManagedObjectContext objectWithID:] メソッドを使用してオブジェクトを引き出すこともできます。引数として privateObjectIDs 配列内の各オブジェクトを渡しますが、この方法はより短くなります。また、フェッチ リクエストを作成し (MagicalRecord には MR_fetchAllWithPredicate: メソッドがあります)、バッチ サイズを設定し、フェッチを手動で実行することを検討することをお勧めします。これにより、Core Data は、返された配列の舞台裏ですべてデータをチャンクにプルして、スレッドのブロックを防ぐことができます。

それが役立つことを願っています!

于 2014-01-29T00:36:06.490 に答える