2012-11-03 21 views
0

最近我開始了一個只需要一個商店的新應用程序(沒有基於文檔的應用程序)。有一段時間我是很高興的思維我終於可以擺脫拋四周的NSManagedObjectContext ......直到我想要在後臺保存:-(使用MagicalRecord保存背景的設計策略

現在我很困惑我自己的代碼,例如:

- (void)awakeFromInsert 
{ 
    [super awakeFromInsert]; 
    [self resetCard]; 
    self.creationDate = TODAY; 
    self.dictionary = [Dictionary activeDictionary]; 
    NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 
    [center postNotificationName:NOTE_NEWCARD object:self];  
} 

[字典activeDictionary]是一個NSManagedObject靜態函數返回一個指針在主線程創建的NSManagedObject。這將背景中造成交叉/上下文錯誤保存。因爲我的程序總是從同店仔細一看,以爲我能避免寫這篇:

[Dictionary activeDictionaryWithContext:...] 

我想用MagicalRecord,只要我總是用相同的後端工作,就可以避免傳遞上下文指針。我應該使用哪個函數來獲取上下文?

[NSManagedObjectContext MR_defaultContext] 
[NSManagedObjectContext MR_context] 
[NSManagedObjectContext MR_contextForCurrentThread] 

在這個例子中,對象在通知中發送自己,幾乎被授予引發更多衝突的東西。

  • 在通知的情況下,我應該總是隻發送objectID?

在我看來,我的對象只有在主環境中運行時纔會發出副作用操作/通知。然而,其中一些副操作會更改我的對象圖,從而創建其他實體的新實例。

  • 如果我用[MagicalRecord MR_saveAll]保存,我可以安全地省略我提到的兩個有問題的函數調用嗎?

  • 我應該承擔的新的背景環境保存的對象將是我的主線程的那些完全相同的副本,而無需調用這些額外的功能呢?

現在我遇到了問題,因爲我從來沒有想過awakeFromInsert爲同一個商店的同一對象運行多次。我在想是這樣的:

- (void)awakeFromInsert 
{ 
    [super awakeFromInsert]; 
    if ([self managedObjectContext] == [NSManagedObjectContext MR_defaultContext]) { 
     [self resetCard]; 
     self.creationDate = TODAY; 
     self.dictionary = [Dictionary activeDictionary]; 
     NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; 
     [center postNotificationName:NOTE_NEWCARD object:self];  
    } 
} 

這應該使運行我awakeFromInsert代碼只有一次,但不會在後臺保存環境。我很擔心如果我這樣做會丟失信息

回答

1

雖然你當然可以通過這種方式發送你的對象,但我會建議那個。請記住,即使在CoreData中有新的父子上下文,NSManagedObjects也是不是線程安全。如果您創建或導入對象,則需要先保存它們,然後才能在另一個上下文中使用它們。

MagicalRecord提供了一種相對簡單的API爲背景節能:

[MagicalRecord saveInBackgroundWithBlock:^(NSManagedObjectContext *localContext){ 
    MyEntity *newEntity = [MyEntity MR_createInContext:localContext]; 

    //perform other entity operations here 
}]; 

此塊爲您完成所有的工作,而不必擔心正確建立的NSManagedObjectContext。

你不應該通過NSManagedObjects通過通知的另一個原因是你不知道接收通知的線程。這可能會導致崩潰,因爲再次,NSManagedObjects是線程安全的不是

您提出的通知方法的另一種替代方法是向NSManagedObjectContextDidSaveNotification添加一個觀察者,然後合併您對該通知的更改。這隻會在您的對象被保存後觸發,並且通過父子關係或持久存儲(舊的方式)來跨越上下文是安全的。

+0

謝謝,我使用的是MagicalRecord 2.0.7,儘管我只使用了一個上下文,但普通的MR_save卻給了一些麻煩,因爲它與它創建的第二個上下文一起工作。最糟糕的是,通知來自第三方面?!?!? – SystematicFrank

+0

我知道NSManagedObjects不是線程安全的,我的問題是我應該如何處理,以及MR_save期間發生了什麼。我看到正在創建第二個上下文,因此我的awakeFromInsert被同一商店的對象調用兩次。如果我的awakeFromInsert代碼僅在當前上下文是主線程的情況下運行,那麼我擔心會丟失信息。現在更新問題... – SystematicFrank

+0

awakeFromInsert被調用兩次,因爲您正在單獨的上下文中創建兩個實例。我想你想要的是創建對象,然後保存,然後在第二個上下文中加載對象。 – casademora