2012-11-27 32 views
1

(答案找到見下文。)NSManagedObjects不被保存 - 逆關係謹防

在下面的代碼,我通過將一些關係的更新約350,000條記錄。然而,最後,我檢查了sqlite數據庫,並且只保留了一小部分關係。其餘的仍然是零。

-update-

在描述問題的代碼,我要解釋的是,dictionaryOfSynsetDictionaries包含預取synset對象。它被組織成包含四個詞典的字典,其中鍵是'n','v','a'和'r'(對於四個詞類,或pos)。每個內部字典都包含對從NSManagedObject分類的synset對象的引用。

每個內部詞典都被稱爲synsetOffset

以下代碼從存儲中獲取所有SYNSET_POINTER對象,並將它們放入數組中。每個SYNSET_POINER對象是指synsetsynsetOffsetpartOfSpeechpos)屬性。它還包含在dictionaryOfSynsetDictionaries

匹配synsetOffsetpos到相應的synset所以現在,在已預取和組織synset對象到字典鏈接SYNSET_POINTER對象到synset的關係,下面的代碼獲取所有的SYNSET_POINTER對象添加到數組中,迭代數組,將synset指針直接通過對應關係鏈接到它們的synset對象。

enter image description here

(上圖爲該SYNSETSYNSET_POINTER對象之間的兩個關係,這是基於原始數據集的組織。他們有兩個不同的目的。對於這個問題,我指的是一對。酮關係)

末端最新情況:

這裏是做更新的代碼:

[request setEntity:[NSEntityDescription entityForName:@"SYNSET_POINTER" inManagedObjectContext:[ManagedObjectContext moc]]]; 
predicate = nil; 
[request setPredicate:predicate]; 
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"synsetOffset" ascending:YES]; 
[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]]; 
NSArray *synsetPointersArray = [[ManagedObjectContext moc] executeFetchRequest:request error:&error]; 

int i = 0; 
int j = 0; 

for(SYNSET_POINTER *pointer in synsetPointersArray) { 
    NSString *pos = pointer.partOfSpeech; 
    NSString *offset = [pointer.synsetOffset stringValue]; 
    pointer.synsetPointer = [[dictionaryOfSynsetDictionaries objectForKey:pos] objectForKey:offset]; 
    error = nil; 
    if (![[ManagedObjectContext moc] save:&error]) { 
     NSLog(@"error with save\n%@\n%@",error.localizedFailureReason, error.localizedDescription); 
     NSLog(@"pause and quit"); 
    } 
    NSLog(@"pos %@, offset %@, pointer %@", pos, offset, pointer); 
    if (j==100) { 
     NSLog(@"%@ %d", pos, i); 
     j=0; 
    } 
    i++; 
    j++; 
} 

在這裏,我正在更新屬性synsetPointer作爲NSNSagedObject類的子類SYNSET_POINTER的指針。我可以看到,在該循環的每次迭代中,synsetPointer關係確實指向到適當的對象,如在本調試器輸出:

2012-11-26 22:03:08.753   [26156:fb03] pos v, offset 5815, pointer <SYNSET_POINTER: 0x404e84f0> (entity: SYNSET_POINTER; id: 0x404d00d0 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET_POINTER/p282133> ; data: { 
    partOfSpeech = v; 
    pointerSymbol = "~"; 
    reverseRelatedSynset = "0x244cd880 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET/p85476>"; 
    sourceTarget = 0000; 
    synsetOffset = 5815; 
    synsetPointer = "0x244cdda0 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET/p83738>"; 
}) 
2012-11-26 22:03:08.822   [26156:fb03] pos v, offset 5815, pointer <SYNSET_POINTER: 0x404e8530> (entity: SYNSET_POINTER; id: 0x404d00e0 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET_POINTER/p285862> ; data: { 
    partOfSpeech = v; 
    pointerSymbol = "@"; 
    reverseRelatedSynset = "0x244cd870 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET/p86470>"; 
    sourceTarget = 0000; 
    synsetOffset = 5815; 
    synsetPointer = "0x244cdda0 <x-coredata://9136BC94-4D77-4DB6-B03F-4F3AA35E2E49/SYNSET/p83738>"; 
}) 

synsetPointersArraysynsetOffset值排序。我可以在Firefox中的sqlite查看器中對錶格進行排序,我發現大部分值都保持爲零。上面的調試輸出顯示它們全部被分配。由於某種原因,他們沒有被保存。

任何人都可以看到這個代碼會阻止一些更新的問題嗎?

回答

1

解決了!

從我提供的所有信息中並不明顯,但我發現圖片中顯示的一對一關係是問題所在。

SYNSET_POINTER.synsetPointer應該指向一個且只有一個SYNSET對象。

但是,它發現多個SYNSET_POINTER對象可以指向單個SYNSET對象

因此,反向關係SYNSET.reverseSynsetPoint應被配置爲一對多雙向關係的一部分。

由於託管對象上下文負責解決反向關係,所以一對一關係意味着先前分配的鏈接自動被取消。將新的SYNSET_POINTER分配給已具有SYNSET_POINTER-SY-SYNSET關係集的SYNSET將在每次更改SYNSET.reverseSynSetPointer時雙向禁用現有鏈接。這會在SYNSET_POINTER端留下一個懸掛鏈接,但託管對象上下文會自動使其無效。

因此核心數據已經設置並保存更改。但是,如我所料,許多這些鏈接被配置後,它們也被取消了。

在我的情況下,我確實不需要反向關係,並將其作爲事後考慮,並認爲我可能會在以後使用它。我的建議是在最初設置時仔細考慮這些類型的逆向關係。否則,他們可能會在以後製造麻煩。

+0

這真的幫助我!謝謝。要注意那些一對一的。 –

0

你的代碼使用非常差的變量名,這使得很難理解你想實現什麼。但是,你似乎在犯一個基本的概念錯誤。

通常,爲了在覈心數據中建立關係,您不會將對其他核心數據對象的引用保存爲這些對象中的屬性。相反,您使用關係並讓核心數據處理外鍵的技巧。爲了向關係中添加對象,請在對象類中使用Core Data生成的訪問器。

退房核心數據編程指南的以下部分:
Relationships and Fetched Properties
Managed Objects

+0

嗨,蒙迪。是的,我必須同意你的名字。我正在移植一個現有的數據集,名稱與其原始文檔一致。我自己也花了相當長的一段時間才明白,名字沒有幫助。我沒有提及有關'dictionaryOfSynsetDictionaries'對象的內容。它包含對我在此更新之前立即提取的所有'synset'對象的引用。這些synset對象大約有150,000個。我會用這個解釋來更新我的問題。 – Jim