1

I'm using MagicalRecord and import data for an entity in this method:

+(void)importEnduserOnBackgroundFromResponse:(id)responseObject
                                     success:(void (^)(QNEnduser *provider))success
                                  andFailure:(void (^)(NSError *error))failure
{
    __block NSManagedObjectID *enduserID;
    __block NSError *importError;
    [MagicalRecord saveWithBlock:^(NSManagedObjectContext *localContext) {
        QNEnduser *enduser = [QNEnduser MR_importFromObject:enduserDict inContext:localContext];

        [localContext obtainPermanentIDsForObjects:localContext.insertedObjects.allObjects error:&importError];
        enduserID = enduser.objectID;
    } completion:^(BOOL successFlag, NSError *saveError) {
        // Check for errors (importError and saveError), if no errors import the entity in the main context and call the success block
        QNEnduser *newEnduser = (QNEnduser*)[[NSManagedObjectContext MR_defaultContext] objectWithID:enduserID];
    }];
}

Note that i've stripped a little bit of code in the completion block because it's not important for this problem.

In Xcode 5, this code works. But in Xcode 6 Beta 6, it throws an exception at [localContext obtainPermanentIDsForObjects:localContext.insertedObjects.allObjects error:&importError];

I have found similar Problems (Getting thread errors when calling obtainPermanentIDsForObjects, Core Data: Do child contexts ever get permanent objectIDs for newly inserted objects?), but they are older and their solution does not work in my case, as you can see, I already try to obtain the permanent IDs for all inserted Objects (even though it would not matter anyway, there are no other inserted objects).

Has anyone else experienced this problem, is it a known Bug in beta 6 and is there a known workarround? Or is it my fault after all?

EDIT

Somehow I can't get the exception - I have an exception breakpoint set in Xcode, but when I put a @try/@catch around the bad line, nothing gets caught.

When stopped at the exception breakpoint, this is the backtrace:

* thread #4: tid = 0x2f2a0, 0x0000000103f19973 libobjc.A.dylib`objc_exception_throw, queue = 'NSManagedObjectContext Queue', stop reason = breakpoint 1.3
  frame #0: 0x0000000103f19973 libobjc.A.dylib`objc_exception_throw
  frame #1: 0x0000000102333dd2 CoreData`-[NSPersistentStoreCoordinator(_NSInternalMethods) obtainPermanentIDsForObjects:error:] + 1458
  frame #2: 0x00000001023aa16d CoreData`__99-[NSManagedObjectContext(_NestedContextSupport) _parentObtainPermanentIDsForObjects:context:error:]_block_invoke + 1037
  frame #3: 0x0000000104f5772d libdispatch.dylib`_dispatch_client_callout + 8
  frame #4: 0x0000000104f465d0 libdispatch.dylib`_dispatch_barrier_sync_f_invoke + 57
  frame #5: 0x000000010233df92 CoreData`_perform + 114
  frame #6: 0x00000001023a9bde CoreData`-[NSManagedObjectContext(_NestedContextSupport) _parentObtainPermanentIDsForObjects:context:error:] + 446
  frame #7: 0x0000000102333592 CoreData`-[NSManagedObjectContext obtainPermanentIDsForObjects:error:] + 498
* frame #8: 0x000000010206fc28 QonnectAPIPod`__75+[QNImportHelper importEnduserOnBackgroundFromResponse:success:andFailure:]_block_invoke(.block_descriptor=<unavailable>, localContext=0x00007fd078dd8d60) + 568 at QNImportHelper.m:129
  frame #9: 0x0000000102142abd QonnectAPIPod`__51+[MagicalRecord(.block_descriptor=0x00007fd078d026b0) saveWithBlock:completion:]_block_invoke + 25 at MagicalRecord+Actions.m:28
  frame #10: 0x00000001023a461e CoreData`developerSubmittedBlockToNSManagedObjectContextPerform_privateasync + 78
  frame #11: 0x0000000104f5772d libdispatch.dylib`_dispatch_client_callout + 8
  frame #12: 0x0000000104f46dcf libdispatch.dylib`_dispatch_queue_drain + 481
  frame #13: 0x0000000104f46b94 libdispatch.dylib`_dispatch_queue_invoke + 112
  frame #14: 0x0000000104f479fc libdispatch.dylib`_dispatch_root_queue_drain + 81
  frame #15: 0x0000000104f47d12 libdispatch.dylib`_dispatch_worker_thread2 + 40
  frame #16: 0x00000001052ebef8 libsystem_pthread.dylib`_pthread_wqthread + 314
  frame #17: 0x00000001052eefb9 libsystem_pthread.dylib`start_wqthread + 13
Community
  • 1
  • 1
MeXx
  • 3,357
  • 24
  • 39
  • Paste your exception and stacktrace – bhargavg Aug 27 '14 at 12:01
  • Do you really declare `importError` outside the block? I don't get a good feeling about that. 1. I'm not sure the NSError** pointer is atomic. 2. If an NSError* gets put at &NSError, what increments its retain count outside the context of your block, provided it was declared outside the block? Does the NSError* get deallocated before it's referenced outside the block... etc. Or maybe you edited that, too. – stevesliva Aug 28 '14 at 03:09
  • Oh you're right, I've added the error declaration back in where it belongs. – MeXx Aug 28 '14 at 06:36
  • This isn't an intended or supported use of `obtainPermanentIDsForObjects`. Save the context instead. In your code, get the user object and ID *after* the save, in the completion handler. – quellish Aug 29 '14 at 21:56
  • @quellish could you provide a sample? I've tried something like that, but was told that bringing the managed object across different threads was a bad idea in [this discussion](https://github.com/magicalpanda/MagicalRecord/issues/781), even though i was just accessing the objectID in the other thread. It made sense to me, after all thats also what apple says (use objectIDs). – MeXx Aug 30 '14 at 10:59

0 Answers0