I'm having trouble dealing with object IDs in CoreData. I'm using MagicalRecord for convenience and have 3 contexts: a private queue working context, a main queue context for UI and parent to the working context, and a private queue saving context that is the parent of the main context.
My goal is to create an object in the working context, save to the persistent store, save it's objectID URL to NSUserDefaults, and then be able to pull out that MO using the objectID later on. However, what I'm finding is that after saving the permanent ID of the object is changing.
In the console output below you can see that after I request the permanent ID the value I get back is "F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1" but later when I list all the objects in CD the only object there has the ID "F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2". p1 vs p2, what happened?
Code:
NSManagedObjectContext *c = [NSManagedObjectContext MR_contextThatPushesChangesToDefaultContext];
[c performBlockAndWait:^{
NSArray *all = [CDBaseAccount MR_findAllInContext:c];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);
CDBaseAccount *a = [CDBaseAccount MR_createInContext:c];
a.accountName = @"foo";
[c MR_saveNestedContexts];
NSLog(@"temp a.objectID = %@", a.objectID);
NSError *error;
if (![c obtainPermanentIDsForObjects:@[a] error:&error]) {
NSLog(@"perm id error: %@", error);
return;
}
NSLog(@"perm a.objectID = %@", a.objectID);
NSURL *u = a.objectID.URIRepresentation;
dispatch_async(dispatch_get_main_queue(), ^{
NSManagedObjectContext *d = [NSManagedObjectContext MR_defaultContext];
NSArray *all = [CDBaseAccount MR_findAllInContext:d];
NSLog(@"count: %d", all.count);
NSLog(@"all accounts = %@", all);
NSManagedObjectID *i = [d.persistentStoreCoordinator managedObjectIDForURIRepresentation:u];
NSError *objWithIdError = nil;
NSManagedObject *o = [d existingObjectWithID:i error:&objWithIdError];
if (objWithIdError != nil) {
NSLog(@"existing object error: %@", objWithIdError);
return;
}
NSLog(@"o = %@", o);
NSLog(@"o.objectID = %@", o.objectID);
});
}];
Console output:
> +[NSManagedObjectContext(MagicalRecord) MR_contextWithStoreCoordinator:](0xa7c9b0) -> Created <NSManagedObjectContext: 0x83522a0>: Context *** MAIN THREAD ***
> count: 0
> all accounts = (
> )
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8353de0) -> Saving <NSManagedObjectContext: 0x8353de0>: Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x8195450) -> Saving <NSManagedObjectContext: 0x8195450>: *** DEFAULT *** Context *** MAIN THREAD ***
> -[NSManagedObjectContext(MagicalSaves) MR_saveWithErrorCallback:](0x83522a0) -> Saving <NSManagedObjectContext: 0x83522a0>: *** BACKGROUND SAVE *** Context *** MAIN THREAD ***
> temp a.objectID = 0x8187ee0 <x-coredata:///CDBaseAccount/tF392AC6A-3539-4F39-AC53-35F9E5B3C9322>
> perm a.objectID = 0x8355800 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2>
> count: 1
> all accounts = (
"<CDBaseAccount: 0x844ca60> (entity: CDBaseAccount; id: 0x844a4c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p1> ; data: <fault>)"
)
> existing object error: Error Domain=NSCocoaErrorDomain Code=133000 "The operation couldn’t be completed. (Cocoa error 133000.)" UserInfo=0x864d8c0 {NSAffectedObjectsErrorKey=(
"<CDBaseAccount: 0x864b8c0> (entity: CDBaseAccount; id: 0x86405c0 <x-coredata://F474F6EE-A225-456B-92EF-AB1407336F15/CDBaseAccount/p2> ; data: <fault>)"
)}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…