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