簡體   English   中英

保存NSManagedObjectContext這個'干凈'時為什么會出現合並錯誤?

[英]Why am I getting a merge error when saving an NSManagedObjectContext this 'clean'?

提前感謝您的幫助。 我今天花了很多時間與此作斗爭,我認為我對框架的運作方式有一些嚴重的錯誤。

我正在開發一個核心數據應用程序,其中實體具有父/子關系。 應用程序在啟動時創建NSManagedObjectContext(MOC)。 當應用程序第一次運行時,它使用異步塊將plist的內容導入第二個MOC(根節點是使用URI和-managedObjectIDForURIRepresentation :)從主MOC獲取的,就在塊完成之前保存第二個上下文。

在我的數據控制器中,我訂閱了NSManagedObjectContextDidSaveNotification,並在發送通知時運行以下代碼:

- (void)backgroundContextDidSave:(NSNotification *)notification {
    if(![notification.object isEqual:self.managedObjectContext]){
        if (![NSThread isMainThread]) {
            [self performSelectorOnMainThread:@selector(backgroundContextDidSave:)
                                   withObject:notification
                                waitUntilDone:NO];
            return;
    }       
        [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];        ;
    }
}

我已經對這段代碼進行了完整性檢查,當然,當第二個MOC保存時,從執行塊的線程調用它,然后延遲,並從主線程運行。 通知對象包含在第二個MOC中導入的所有對象,包括我們接下來要處理的兩個對象。

完成后,我運行以下代碼,該代碼位於對象所屬的NSManagedObject子類的方法中,它只是意味着從子父中刪除子代:

TreeEntry *oldParent=self.parent; //keep a pointer to the old parent around so we can delete self from the children

// These next four lines are a sanity check to make sure that both objects are on the same MOC we're saving
NSManagedObjectContext *selfContext=self.managedObjectContext;
NSManagedObjectContext *parentContext=self.parent.managedObjectContext;
NSManagedObjectContext *sharedContext=[[DataController sharedDataController] managedObjectContext];
assert([selfContext isEqual:parentContext] && [selfContext isEqual:sharedContext]);

// now we fault the two objects to make sure we can not possibly have them or any changes 
// to them in the state of the main MOC, by this time the second MOC is long gone
[sharedContext refreshObject:self.parent mergeChanges:NO];
[sharedContext refreshObject:self mergeChanges:NO]; 

// up to this point, sharedContex.insertedObjects, sharedContext.updatedObects and sharedContext.deletedObjects
// have all contained no objects at all. None of the above was necessary as the MOC held no changes at all
[sharedContext saveChanges]; // we save it to, well, just to make sure I guess, I may be going crazy

// Now we carry out two changes to the objects, problem occurs if only one change is carried out,
// I'm showing both to show that there relationship is being kept consistent and valid
self.parent=nil;
[oldParent removeChild:self];


// When the next line is run the save fails with a merge conflict
[sharedContext saveChanges];

最后一次保存失敗,出現Cocoa錯誤133020,這是合並失敗。 錯誤中的兩個NSMergeConflicts與我們正在處理的條目(self和self.parent)有關。

我只是不明白這是怎么回事。 對象在被修改時沒有狀態,因此它們必須從商店加載。 進行兩個簡單的更改,然后在直接保存它們之后發生合並沖突。 怎么可能? 沒有別的東西搞砸了商店,我們只是加載了它的對象。

我知道我可以更改合並政策,但我不想在不了解正在發生的情況下這樣做。

有任何想法嗎? 我確信這只是我的心理模型,如果發生的事情是錯的,但我一直都沒能把它整理好!

好吧,這是我對框架如何工作或更准確的NSManagedStoreCoordinator緩存的一個基本誤解。

當我保存后台上下文時,更改將轉到磁盤,但顯然NSManagedStoreCoordinator(兩個上下文共享)不會更新或使其緩存無效。

當我刷新主MOC中的對象時,用於重新填充它們的數據來自緩存,緩存仍然具有舊數據。 它不會從磁盤重新加載。 解決方案是使用[MOC setStalenessInterval:0.0]強制從磁盤重新加載。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM