5

我有一個NSManagedObject沒有反映後臺線程保存它的上下文後所做的更改持久存儲的問題。NSManagedObject不反映後臺線程後的變化NSManagedObjectContextDidSaveNotification

的設置

在一個簡單的測試應用程序,我有一個列出我的核心數據持久性存儲中的所有對象的一個​​窗口,一個搜索框來篩選結果的文本字段顯示名稱所選項目的名稱,並允許更改名稱。

綁定如下:

 
ArrayController --> AppDelegate --> ManagedObjectContext 
TableView Col 1 --> ArrayController --> values --> arrangedObjects.widgetName 
TableView Col 2 --> ArrayController --> values --> arrangedObjects.uid 

SearchField --> ArrayController --> predicate --> filterPredicate 

TextField --> ArrayController --> value --> selection.widgetName 

我也有一個按鈕,開始從web服務器數據的背景(的NSOperation)提取。

進程

當用戶點擊的刷新按鈕,一個的NSOperation被踢關閉該進入和異步抓住窗口小部件,解析響應,對於本地窗口小部件檢查,以刪除不在響應中,要添加的新的小部件不存儲在本地,以及現有的本地小部件應該使用從服務器檢索的數據進行更新。

一旦處理完畢,主上下文是使用通知:

[mainContext performSelectorOnMainThread: 
     @selector(mergeChangesFromContextDidSaveNotification:) 
           withObject:notification 
          waitUntilDone:YES]; 

我在測試主控制器,顯示了通過改變得很好,主控制器得到通知去的觀察員。

的問題

如果我做出改變使用文本字段選擇的對象,當在後臺線程中的數據被保存在UI對象不更新,以反映這些變化(即它不會覆蓋與來自服務器的更改的用戶界面)。

例如,給出以下三個部件和ID的:

 
Test Name 1 | ID 123 
Test Name 2 | ID 234 
Test Name 3 | ID 345 

如果我在Test Name 2的UI名稱更改爲Renamed 2我有以下幾點:

 
Test Name 1 | ID 123 
Renamed 2 | ID 234 
Test Name 3 | ID 345 

當我刷新背景,我想要列表反映服務器的狀態,即回到:

 
Test Name 1 | ID 123 
Test Name 2 | ID 234 
Test Name 3 | ID 345 

相反,它仍然是:

 
Test Name 1 | ID 123 
Renamed 2 | ID 234 
Test Name 3 | ID 345 

我知道,因爲如果我殺了在Xcode中並重新啓動應用程序的持久性存儲進行了更新,顯示所需的信息。如果我正常退出應用程序,則在應用程序關閉時將更改後的值寫入存儲區,重新打開時會顯示重命名的值。

我已經試過

我知道正在發送的消息形式的背景,主要內容和我所知道的數據被保存到存儲。因此,我認爲這個問題是主環境並沒有像我期望的那樣合併,或者我需要以某種方式強制數組控制器從持久存儲中獲取並丟棄它的上下文。

  • 我試圖processPendingChanges:在商店的通知節約,但我懷疑,我只是寫了Renamed 2商店。
  • 我曾嘗試陣列控制器上做一個rearrangeObjects,但隨着陣列控制器正在處理的主要方面,我懷疑這是做什麼
  • 我曾嘗試陣列控制器上做了fetch:nil做從一個取持久存儲,但我再次懷疑主要上下文覆蓋Renamed 2的值,因爲它尚未保存。
  • 我試圖fetchWithRequest:nil merge:NO error:&error陣列控制器按照蘋果的文檔上,但仍這似乎並沒有改變顯示值

認爲需要做的是陣列控制器,以保存其數據直到我寫入後臺存儲數據,然後在數組控制器上進行提取將導致數據按我的預期準確。如果情況確實如此,我將如何告訴數組控制器執行此操作,或者如果主要managedObjectContext以某種方式保存,數組控制器是否僅通過綁定知道更改?

我可以通過從持久性存儲中獲取數據,將該數據放在數組中並在數組控制器上執行setContent:,然後在持久性存儲被保存時重複此操作,但這種感覺完全錯誤,而不是提及那麼必須跟蹤數組控制器的選定狀態(以及可能由於該主要選擇而可能發生的任何子陣列選擇)的問題。

我離開了基地嗎?我顯然在這裏失去了一些東西。

任何智慧或建議的話將非常感激。

回答

3

啊沮喪的力量加上決心。我不確定這是否是最好的或推薦的方法,但它肯定符合我的需求。

我的目標是在保存後臺更新之前保留任何未保留的更改,或者在保存後臺更新之前將其丟棄。兩者在我的世界中都有相同的用途(服務器數據總是正確的)。

原來我只是需要在我的NSOperation添加一個觀察者:

NSNotificationCenter * nc = [NSNotificationCenter defaultCenter]; 
[nc addObserver:self 
     selector:@selector(prepareMerge:) 
      name:NSManagedObjectContextWillSaveNotification object:ctx]; 

它調用了操作的方法:

-(void)prepareMerge:(NSNotification *)notification { 

    [[NSNotificationCenter defaultCenter] 
     postNotificationOnMainThreadName:@"SaveNow" 
            object:nil]; 
} 

的通知發送給主線程(禮貌NSNotificationCenter上的一個類別發佈在cocoanetics.com),這是在主線程的相關類中收聽的:

[[NSNotificationCenter defaultCenter] addObserver:self 
             selector:@selector(saveNow:) 
              name:@"SaveNow" 
              object:nil]; 

當然,這實際上使得變化的方法:

-(void)saveNow:(NSNotification *)aNote { 

    [[self managedObjectContext] rollback]; 
} 

陣列控制器和已更新值的任何其他UI組件回滾保存被提交權利之前。保存經過並且舊的本地值全部被新值替換。

工作完成。