【发布时间】:2010-10-21 01:11:04
【问题描述】:
我在使用 Core Data 时遇到了一个非常令人困惑的问题。在我的 Core Data 存储中,对于现有的 Core Data 对象,我正在检查是否存在关系,如果不存在,我会像这样创建对象(这是 AFFingerprintGeneratorOperation 上的一个方法):
NSManagedObjectContext *newContext = [[NSManagedObjectContext alloc] init];
[newContext setMergePolicy:NSOverwriteMergePolicy];
NSPersistentStoreCoordinator *sharedStoreCoordinator = [[AFMainController sharedInstance] persistentStoreCoordinator];
[newContext setPersistentStoreCoordinator:sharedStoreCoordinator];
[self setManagedObjectContext:newContext]; // retaining property
[newContext release];
NSEntityDescription *fetchedTagSetEntity = [NSEntityDescription entityForName:@"FetchedTagSet"
inManagedObjectContext:newContext
];
AFTrack *retrievedTrack = (AFTrack *)[newContext objectWithID:[self trackObjectID]];
[self setTrack:retrievedTrack];
if (! retrievedTrack.fetchedTagSet) {
AFFetchedTagSet *newFetchedTagSet = [[AFFetchedTagSet alloc] initWithEntity:fetchedTagSetEntity
insertIntoManagedObjectContext:newContext];
[[retrievedTrack storedTrack] setFetchedTagSet:newFetchedTagSet];
[newFetchedTagSet setStoredTrack:[retrievedTrack storedTrack]];
}
AFTrack、AFFetchedTagSet 和 AFStoredTrack 都是 Core Data 对象。 AFFetchedTagSet 和 AFStoredTrack 位于磁盘核心数据存储中,而 AFTrack 位于单独的内存核心数据存储中。
请注意,由于 AFStoredTrack 对象位于单独的存储中,因此我需要像这样获取它(这是 AFTrack 上的一个方法):
NSManagedObjectContext *objectContext = [self managedObjectContext];
NSPersistentStoreCoordinator *coordinator = [objectContext persistentStoreCoordinator];
NSString *URIString = [self storedTrackObjectIDString];
AFStoredTrack *theStoredTrack = nil;
if (URIString) {
NSURL *objectURL = [NSURL URLWithString:URIString];
NSManagedObjectID *storedTrackObjectID = [coordinator managedObjectIDForURIRepresentation:objectURL];
theStoredTrack = (AFStoredTrack *)[objectContext objectWithID:storedTrackObjectID];
}
return theStoredTrack;
由于这是 AFTrack 上的一个方法,它只是检索 AFTrack 自己的托管对象上下文,因此第一个摘录中的代码应该始终对所有操作使用完全相同的托管对象上下文。
但是,在第一个摘录中,在使用新对象调用 setFetchedTagSet: 并尝试保存核心数据存储后,我收到此错误:
"Dangling reference to an invalid object." = "<null>";
NSAffectedObjectsErrorKey = (
"<AFStoredTrack: 0x11550eef0> (entity: StoredTrack; id: 0x101eb57d0 <x-coredata:///StoredTrack/tF7F5568E-2959-4786-B73D-B7AC6586F5B9121> ; data: {\n fetchedTagSet = \"0x11c956b60 <x-coredata:///FetchedTagSet/tF7F5568E-2959-4786-B73D-B7AC6586F5B9124>\";\n fingerprint = \"ASPtPiNHPC7fGSYXTxtfFboMCg7BCxYQ+gZRCL4FWQdzBD8HPw\";\n persistentID = nil;\n status = 3;\n updateAlbumName = nil;\n updateArtistName = nil;\n updateArtwork = nil;\n updateGenre = nil;\n updateLyrics = nil;\n updateReleaseYear = nil;\n updateTrackName = nil;\n})"
);
NSLocalizedDescription = "storedTrack is not valid.";
NSValidationErrorKey = storedTrack;
NSValidationErrorObject = "<AFFetchedTagSet: 0x11c956ac0> (entity: FetchedTagSet; id: 0x11c956b60 <x-coredata:///FetchedTagSet/tF7F5568E-2959-4786-B73D-B7AC6586F5B9124> ; data: {\n ampliFindPUID = nil;\n fingerprint = nil;\n matchAlbum = nil;\n matchLyrics = nil;\n matchTrackName = nil;\n matchTrackNumber = 0;\n storedTrack = \"0x101eb57d0 <x-coredata:///StoredTrack/tF7F5568E-2959-4786-B73D-B7AC6586F5B9121>\";\n})";
NSValidationErrorValue = "<AFStoredTrack: 0x11550eef0> (entity: StoredTrack; id: 0x101eb57d0 <x-coredata:///StoredTrack/tF7F5568E-2959-4786-B73D-B7AC6586F5B9121> ; data: {\n fetchedTagSet = \"0x11c956b60 <x-coredata:///FetchedTagSet/tF7F5568E-2959-4786-B73D-B7AC6586F5B9124>\";\n fingerprint = \"ASPtPiNHPC7fGSYXTxtfFboMCg7BCxYQ+gZRCL4FWQdzBD8HPw\";\n persistentID = nil;\n status = 3;\n updateAlbumName = nil;\n updateArtistName = nil;\n updateArtwork = nil;\n updateGenre = nil;\n updateLyrics = nil;\n updateReleaseYear = nil;\n updateTrackName = nil;\n})";
但 AFFetchedTagSet 和 AFStoredTrack 对象似乎都是有效的,因为它们的 id 匹配,并且这些对象的对象上下文仍然存在并由 AFFingerprintGeneratorOperation 对象保留。
我已经看到了这个 CoreData: "Dangling reference to an invalid object." error 和这个 http://lists.apple.com/archives/cocoa-dev/2009/Nov/msg00190.html ,但是这两个链接似乎都没有帮助。前者似乎说关系不好(我不这么认为),后者说要避免在 awakeFromFetch 中改变关系,据我所知我没有这样做。
有什么帮助吗?
【问题讨论】: