2017-10-18 71 views
0

如果我在覈心數據存儲中有100,000個實體,如何在後臺線程中訪問/加載/獲取所有100,000個實體,並且一旦加載/提取訪問這些實體在主線程/其他線程上的屬性? (例如,顯示UICollectionView中的項目)我將使用批處理來避免將所有100,000個加載到內存中 - 但我需要確切知道在初始加載後有多少個內存。如何在後臺線程上讀取核心數據,同步在主線程上讀取結果?

事情是這樣的:

// The load occurs on a background thread 
[self loadCoreData: ^{ 
    // Once loaded, dispatch back onto the main thread to get the number of 
    // entities, or I could do something like [self getEntityMatchingProperties:...] 
    // etc. the point being it accesses entity information that has been loaded but 
    // on a different thread. 
    dispatch_async(dispatch_get_main_queue(), ^{ 
     self.title = [self getNumberOfCoreDataEntities]; 
    }); 
}]; 

編輯:另一個(更準確的例子):

- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 

    // The load occurs on a background thread 
    [self loadCoreData: ^{ 
     [self.collectionView reloadData]; 
    }]; 
} 

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section { 
    return [self numberOfItemsLoadedFromCoreData]; 
} 

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { 
    ... 
    Entity *entity = [self getItemLoadedFromCoreDataAtIndexPath:indexPath]; 
    ... 
} 

在第二個例子中,我試圖用一個NSFetchedResultsController我想 - 是否有任何全這種類型的方法的例子?我所看到的所有這些處理片段都是在主環境中執行取指操作 - 這將在主線程上完成工作。

+0

我很生疏,但你的代碼片段似乎只是在主線程上運行getNumberOfCoreDataEntities,而這似乎是擊敗了目的。我覺得你應該在發送回主線程之前發出這個呼叫。即將該調用的結果存儲在變量中,然後將該變量分配給主線程上的self.title。 – ghostatron

+0

@ghostatron我可以理解這一點,當然。也許這是一個糟糕的例子。考慮一個例子,在被加載的視圖上,我想開始一個長時間運行的加載/獲取操作。然後在一個完全不同的方法中,我想訪問核心數據實體的數量,即在「collectionView:numberOfItemsInSection」調用等。 – Zach

+1

如果這只是一個簡單的例子,那麼我很抱歉。至於跨線程邊界傳遞管理對象,我認爲這是一個根本性的禁止。您可以創建自己的類來存儲值並將其傳遞給對象,也可以使用託管對象ID(這是線程安全的)進行重新獲取。 – ghostatron

回答

1

您似乎在重塑NSFetchedResultsController,它將處理您在此處需要的一切。你爲自己做了不必要的事情。這是一個普遍的需求,蘋果公司讓你覆蓋。使用您的獲取請求創建NSFetchedResultsController,並實現您的集合視圖方法,以根據索引路徑向其請求對象。作爲獎勵,NSFetchedResultsController委託方法可用於更新您的收藏視圖,如果基礎數據發生變化。

+0

感謝您的回覆!我正在嘲笑某些東西,但是我將什麼'ManagedObjectContext'傳遞給'NSFetchedResultsController'?如果它是主要上下文,那麼不會在提取發生時阻止UI?在我的應用程序中,這是一個可能持續數秒的獲取,絕對不希望只是在那裏凍結。 – Zach

+0

它用於UI,因此您通常會使用主要上下文。它也可以自行緩存數據以提高性能,並且它足夠聰明,不會將每個對象一次加載到內存中。 –