2013-04-03 72 views
2

我有一個有趣的問題,我似乎無法找到解決方案 - 我有兩個託管對象上下文,'主要'和'支持'。 'Main'使用NSMainQueueConcurrencyType創建,'backing'使用'NSPrivateQueueConcurrencyType'創建。此外,「支持」已被設置爲主要的父項。NSManagedObjectContextDidSaveNotification合併和deletedObjects

我想對支持MOC執行(可能很貴)的寫操作,然後將這些更改(完成時)冒泡到主上下文,從而使我的UI更新由於使用了NSFetchedResultsController。我的問題如下 - 看起來在調用mergeChangesFromContextDidSaveNotification之後,主MOC上的deletedObjects屬性被使用後備隊列的後臺操作中刪除的所有對象填充。

作爲一個例子,下面是一些代碼。

[appDelegate.backingContext performBlock:^{ 

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Parent"]; 
    NSArray *objects = [appDelegate.backingContext executeFetchRequest:fetchRequest error:nil]; 
    for(Parent *parent in objects) { 
     NSMutableOrderedSet *children = [parent mutableOrderedSetValueForKey:@"children"]; 
     for(Child *child in children) { 
      [appDelegate.backingContext deleteObject:child]; 
     } 
     [children removeAllObjects]; 

     for(int i=0;i<3;i++) { 
      Child *child = [NSEntityDescription insertNewObjectForEntityForName:@"Child" 
                 inManagedObjectContext:appDelegate.backingContext]; 
      child.name = [NSString stringWithFormat:@"Child #%i", i]; 
      [children addObject:child]; 
     } 
    } 

    [appDelegate.backingContext save:nil]; 
}]; 

,並在我的應用程序委託

- (void)mergeContextChanges:(NSNotification *)notification { 
    [self.mainContext performBlock:^{ 
     NSLog(@"Before merge: updates - %i, inserts - %i, deletes - %i", 
      self.mainContext.updatedObjects.count, 
      self.mainContext.insertedObjects.count, 
      self.mainContext.deletedObjects.count); 
     [self.mainContext mergeChangesFromContextDidSaveNotification:notification]; 
     NSLog(@"After merge: updates - %i, inserts - %i, deletes - %i", 
      self.mainContext.updatedObjects.count, 
      self.mainContext.insertedObjects.count, 
      self.mainContext.deletedObjects.count); 
    }]; 
} 

這裏的日誌說什麼的變化已經合併之後 -

2013-04-03 00:51:40.476 CoreDataTest[41617:c07] Before merge: updates - 0, inserts - 0, deletes - 0 
2013-04-03 00:51:40.477 CoreDataTest[41617:c07] After merge: updates - 0, inserts - 0, deletes - 3 

你會注意到,在右鍵報道3個對象待定刪除。據我所知,這是不正確的 - 不應該mergeContextChanges:導致(否則完全沒有觸及)上下文的狀態不顯示待處理的更改?這種方法的重點在於更改已經提交給持久存儲。

我在這裏錯過了什麼?

回答

2

mergeChangesFromContextDidSaveNotification:文檔說:

此方法刷新已在其它上下文被更新的任何對象,故障在任何新插入的對象,並調用DeleteObject的:在那些已被刪除

哪(根據我的理解)與您的結果一致。

+1

是的 - 經過一番思考後,這種說法很有道理。可以說,如果MOC不是首先對MOC進行重新編程的話,MOC不應該將該對象標記爲待定刪除。我可以明白爲什麼如果這是你想要這樣做 - 它可能出現在關係中,或者有人可能會提到它。但是,如果這完全在MOC的國家內部,我不明白它爲什麼需要標記。 – dpratt

+0

你有沒有找到解決辦法,所以合併不會觸發「hasChanges」標誌? (謝謝!) –

0

這些對象可能在主要上下文中被刪除(刪除之前)。
由於您的mainContext父項是後備,因此可以將這些更改提交到父上下文(在mainContext上執行保存)。
保存不應該花費很長時間,因爲它沒有提交到持久性存儲區,而只提交給父上下文。

您可以將這些項目保留在主要上下文中,直到它被應用程序中的另一個流程保存爲止。
您的用戶界面將響應這些項目的刪除。

+0

我在上面的示例中執行的唯一提取是在備份上下文中獲取,刪除並創建子對象的提取。我不明白爲什麼刪除會顯示爲空白主環境中的掛起更改。另外,我不想經常在主要上下文中保存 - 重點在於主要上下文旨在是隻讀的,而支持的上下文則是數據變異的地方。 – dpratt