0

很多时候,我在我的应用程序中推送视图控制器并从核心数据中获取对象以填充UI。现在,我通常在主线程中执行viewDidLoad操作,我确信有更好的方法可以在不同的线程上执行此操作。目标c - 在view中的核心数据对象获取DidLoad

如果确实线程是这里的路线,我没有很多线程在Objective C中的经验,所以如果有人能够向我展示代码示例,我将非常感激。

而且我知道核心数据不是线程安全的,所以我应该做任何额外的工作以保证安全?

回答

2

你应该使用NSFetchedResultsController。它将为您管理批处理,并只加载当时需要的内容。这不仅仅是表格视图。您可以在没有单独线程的情况下执行此操作(只要您的数据库不太大,并且您的提取没有太复杂的谓词,需要访问数据库中的每条记录)。

作为FRC的替代方案,或者在需要所有记录的情况下,可以使用单独的线程来获取对象,然后将它们呈现给主线程。

这些都是难以解释的单个SO答案,所以如果它仍然没有意义,请参阅核心数据并发编程指南。或者,如果你想加载所有的东西,并有一些控制,你可以做这样的事情。注意:我认为这种双重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... 
     }]; 
    }   
}]; 
+0

在所有我的应用我用一个建设部和各阶层之间共享,这是必要建立两个不同的邮电部? – Eyal 2012-04-25 16:54:49

+0

您不能从多个线程访问MOC。所以,你想在一个单独的线程中做与数据库相关的任何事情,你必须使用不同的MOC。但请注意,第一句话。在这种情况下,如果你只是使用一个NSFetchedResultsController,你不需要一个单独的MOC,因为它将在主线程上获取。 – 2012-04-25 17:34:29

+0

所以mainMOC可以是共享的,我只需要每次都创建workMoc?我不明白你在说什么NSFetchedResultsController,如果我使用它,我仍然需要在单独的线程中使用它否?它也可以阻止主线程没有? – Eyal 2012-04-26 08:30:39