2

我正在通過核心數據開發一個應用程序,我需要在後臺線程中執行一些計算來創建基於特定NSManagedObject的xml文件。在後臺線程中恢復NSManagedObject關係

以下文檔中,我設置了NSOperation子類。這個類有類似下面的屬性:

@property (nonatomic, retain) NSArray* objectIDs; 

其中objectIDs是管理對象id(的NSManagedObjectID型)的陣列。根據文檔,這是必需的:NSManagedObject不是線程安全的。

mainNSOperation的子類,我做了以下內容:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

NSManagedObjectContext *exportContext = [[NSManagedObjectContext alloc] init]; 
[exportContext setPersistentStoreCoordinator:[self persistentStoreCoordinator]]; 

for (NSManagedObjectID* objectID in self.orderObjectIDs) { 

    NSError* error = nil; 
    Order* order = (Order*)[exportContext existingObjectWithID:objectID error:&error]; 

    // order.someRelationship is fault here... 

    // Create XML file here... 
} 

[exportContext reset]; 
[exportContext release], exportContext = nil; 

[[NSNotificationCenter defaultCenter] postNotificationName:kRegisterComplete object:self]; 

[pool drain]; 
pool = nil; 

裏面的for環路我取使用NSManagedObjectContextexistingObjectWithID:error方法合適的對象,因爲

不像objectWithID :,這個方法永遠不會返回一個錯誤。

該方法有效。我能夠檢索檢索到的對象的屬性。唯一的問題是關係被認爲是錯誤。

說了這個,我有兩個問題。

首先,這是在後臺線程中使用fecth NSManagedObject的正確方法嗎? 那麼,如何獲取for循環中每個獲取對象的關係?我是否必須創建NSFetchedRequest以基於通過ID獲取的特定對象獲取關係對象?

預先感謝您。

回答

2

你爲什麼在乎這種關係是一種錯誤?訪問它將填補故障並返回數據,你是否擔心磁盤I/O出於某種原因?

您可以嘗試使用預取,以減輕一些I/O開銷,但它的效用是有限的對實體是牽強的關係:

https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html

在這種情況下,你將創建一個取與像這樣的謂詞要求:

[NSPredicate predicateWithFormat:@"SELF == %@", objectID]; 

,將返回到你只有你想要的管理對象,並與關係預先擷取的關係不會有錯。

您可以通過使用IN子句和獲取所有對象一次進一步優化這樣的:

[NSPredicate predicateWithFormat:@"SELF IN (%@)", desiredObjectIDs]; 
+0

+1您的建議。你是說我可以使用* setRelationshipKeyPathsForPrefetching創建一個* NSFetchRequest *和完美關係:*?我是Core Data的新成員,我不清楚何時會出現錯誤。先謝謝你。 – 2012-04-01 10:26:38

+0

是的,您可以創建獲取請求並傳遞所需關係關鍵路徑的NSArray,即[NSArray arrayWithObject:@「someRelationship」]。這會導致錯誤在發生時被執行,從而消除額外的I/O。 – ImHuntingWabbits 2012-04-02 04:26:24

0

你需要確保以下幾點:

  • 之前你繞過任何對象您的ID - [NSManagedObjectContext obtainPermanentIDsForObjects:error:]在原始線程上。

(在主線程)

[managedObjectContext obtainPermanentIDsForObjects:objectIDs error:nil] 
  • 試圖從另一個線程(包括它們的關係)訪問這些對象之前,您需要保存原始線程的NSManagedObjectContext。否則,對象將不會存在於持久性中,並且後臺線程將無法獲取它(或其他關係)。確保這一點的最簡單方法是在NSOperation執行開始時在主線程上調用阻塞保存。例如:

dispatch_sync(dispatch_get_main_queue(), { [managedObjectContext save:nil]; });

您可以製作一個NSFetchRequest或直接訪問取決於哪種方式更方便的關係;可能直接訪問關係。在日常工作結束時,您不需要撥打[NSManagedObjectContext reset]

+0

謝謝您的回覆。託管對象已經保存在商店中,所以我不需要調用* obtainPermanentIDsForObjects *。那麼,你能解釋爲什麼我不需要調用* [NSManagedObjectContext reset] *嗎? – 2012-04-01 10:32:43

+0

重置丟棄並使該特定上下文中的NSManagedObjects無效。 (放棄未保存的更改,使NSManagedObjects的所有實例無效)由於您正在釋放上下文,因此該步驟是多餘的。 – lorean 2012-04-02 21:20:26

相關問題