(找到答案。见下文。)
在下面的代码中,我通过链接一些关系来更新大约 350,000 条记录。但是,最后,我检查了 sqlite 数据库,只保存了一小部分关系。其余的仍然为零。
-更新-
在描述有问题的代码之前,我应该解释一下dictionaryOfSynsetDictionaries
包含预取的synset
对象。它被组织成一个包含四个字典的字典,其中键是“n”、“v”、“a”和“r”(用于四个词性,或pos
)。每个内部字典都包含对synset
对象的引用,这些对象是 NSManagedObject 的子类。
每个内部字典都以所谓的synsetOffset
.
下面的代码从存储中获取所有SYNSET_POINTER
对象并将它们放入一个数组中。每个对象通过和( ) 属性SYNSET_POINER
引用一个。它还包含一个关系,该关系将对象链接到by 匹配和对应的 insynset
synsetOffset
partOfSpeech
pos
SYNSET_POINTER
synset
synsetOffset
pos
synset
dictionaryOfSynsetDictionaries
因此,现在,在将synset
对象预取并组织到字典中之后,以下代码将所有SYNSET_POINTER
对象获取到一个数组中,遍历数组,通过对应关系将同义词指针直接链接到同义词集对象。
SYNSET
(上图显示了和对象之间的两种关系SYNSET_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
NSManagedObject 的子类 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>";
})
synsetPointersArray
是按值排序的synsetOffset
。我可以在 Firefox 的 sqlite 查看器中对表格进行排序,我看到大多数值仍然为零。上面的调试输出显示它们都已分配。由于某种原因,他们没有得救。
任何人都可以看到此代码的问题会阻止某些更新吗?