I'm having a really confounding problem using Core Data. In my Core Data store, for an existing Core Data object, I'm checking whether a relationship exists, and if not, I create the object like so (this is a method on 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, and AFStoredTrack are all Core Data objects. AFFetchedTagSet and AFStoredTrack are in an on-disk Core Data store, while AFTrack is in a separate in-memory Core Data store.
Note that since the AFStoredTrack object is in a separate store, I need to fetch it like so (this is a method on 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;
Since this is a method on AFTrack, it simply retrieves the AFTrack's own managed object context, so the code in the first excerpt should always use the exact same managed object context for all operations.
However, in the first excerpt, after calling setFetchedTagSet: with the new object, and attempting to save the Core Data store, I get this error:
"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})";
But both the AFFetchedTagSet and AFStoredTrack objects seem to be valid, as their ids match up, and the object context for these objects still exists and is retained by the AFFingerprintGeneratorOperation object.
I've seen this http://stackoverflow.com/questions/2003648/coredata-dangling-reference-to-an-invalid-object-error and this http://lists.apple.com/archives/cocoa-dev/2009/Nov/msg00190.html , but neither link seems to help. The former seems to say that a relationship is bad (which I don't think it is), and the latter says to avoid changing relationships in awakeFromFetch, which as far as I can tell I'm not doing.
Any help?