0

私は 9gag アプリに非常によく似たアプリを作成していますが、スムーズなスクロールに苦労しているため、メインスレッドからすべてを取得しようとしています。困ったのはCore Dataです。

次のような独自のスレッドを作成するクラス PhotoSource があります。

@property (nonatomic) dispatch_queue_t photoSourceThread;
...
dispatch_async(self.photoSourceThread, ^{ ... });

そして、コアデータのみを扱う別のクラスがあります。

@property (nonatomic, strong) TLCoreDataManager *coreDataManager;

次のように、TLCoreDataManager への呼び出しを含め、PhotoSource クラスのすべてがそのスレッド内で発生します。

dispatch_async(self.photoSourceThread, ^{
Photo *storedPhoto = [self.coreDataManager getPhotoWithURLString:urlString];
...
});

うまくいくこともありますが、アプリを起動した直後に NSFetchRequest[s] からの結果が 0 になり、どうすればよいかわかりません。何が間違っているのでしょうか?さらにコードが必要な場合はお知らせください。

ありがとう

4

1 に答える 1

3

マルチスレッド環境で CoreData を使用してデータを変更し、最終的に GUI を更新するには、変更をメイン キュー ベースのコンテキスト (コア データ ベースのアプリケーションによって生成されるデフォルト コード内のデフォルト コンテキスト) にマージする必要があります。データに加えられた変更をリッスンするには、フェッチ結果コントローラーを使用することをお勧めします。

次のようなものを使用できます。

/*!
 @see http://developer.apple.com/library/ios/#documentation/cocoa/conceptual/CoreData/Articles/cdConcurrency.html
 */
- (void) doSomethingInBackgroundWithoutBlocking:(NSPersistentStoreCoordinator*)coordinator
{
    NSManagedObjectContext* bgContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
    [bgContext setPersistentStoreCoordinator:coordinator];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(mergeChanges:) //merge to your main context
                                                 name:NSManagedObjectContextDidSaveNotification
                                               object:bgContext];
    [bgContext performBlock:^{
        //Do somethig with your persistent store data
        //Objects fetched here will only be available for this context
        //And on its own queue
        //Probably need to save & merge to main context so that the fetch results controller will be updated
        //remove the observer
    }];
}
于 2013-04-01T09:45:42.600 に答える