2012-11-27 21 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