0

我正在制作一个与 9gag 应用程序非常相似的应用程序,并且我正在努力获得平滑滚动,所以我试图让所有内容都脱离主线程。给我带来麻烦的是Core Data。

我有一个类 PhotoSource,它创建了自己的线程,如下所示:

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

我还有另一堂课,它只处理核心数据:

@property (nonatomic, strong) TLCoreDataManager *coreDataManager;

PhotoSource 类中的所有内容都发生在它的线程中,包括对 TLCoreDataManager 的调用,如下所示:

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 回答