EXC_BAD_ACCESS when trying to save from child managed context to parent

automatic-ref-counting, core-data, exc-bad-access

Solution

The problem turns out to be an iOS 5 bug where parent contexts apparently cannot see their children's new relationships. Forcing Core Data to obtain permanent object IDs before trying to save fixes the problem, like so:

[moc obtainPermanentIDsForObjects:@[rating] error:&error];
[moc save:&error];   // --> WORKS NOW

Problem

I have an EXC_BAD_ACCESS that is killing me. I cannot see where it could be coming from. ARC code. SymptomRating is a managed object, of course: ``` __block DPLSymptomRating *rating; self.editMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; // retained: strong NSManagedObjectContext *moc = self.editMOC; //editSymptom.managedObjectContext; [moc performBlockAndWait:^{ NSError __autoreleasing *error = nil; moc.parentContext = DPLPersonalHxDataStore.shared.managedObjectContext; rating = [NSEntityDescription insertNewObjectForEntityForName:@"SymptomRating" inManagedObjectContext:moc]; [moc assignObject:rating toPersistentStore:[NSPersistentStore MR_defaultPersistentStore]]; rating.ratingCode = @101; rating.symptomCode = 1; rating.displayName = @"debug"; NSAssert(rating!=nil, @"Cannot edit nil rating"); NSAssert(rating.managedObjectContext==moc, @""); NSLog(@"validates for insert: %@", [rating validateForInsert:&error]?@"true":@"false"); NSAssert(error==nil,@""); NSLog(@"inserted objects: %@", moc.insertedObjects); // 1 object, from above NSLog(@"updated objects: %@", moc.updatedObjects); // empty NSLog(@"deleted objects: %@", moc.deletedObjects); // empty [moc save:&error]; // -->FAIL: EXC_BAD_ACCESS (code=2, address=0x2) NSLog(@"can we get here?"); // NOPE NSAssert(error==nil, @""); }]; ``` This crashes with the same error whether the concurrency type is Main or Private, and with or without -performBlock: or -performBlockAndWait: I have NSZombieEnabled (I think -- don't know how to verify if it's actually working). Backtrace: ``` frame #0: 0x019c0098 libobjc.A.dylib`objc_msgSend + 12 frame #1: 0x0087e5e0 CoreData`_PFObjectIDFastHash64 + 96 frame #2: 0x01fb48d0 CoreFoundation`__CFDictionaryHashKey + 32 frame #3: 0x01f0a114 CoreFoundation`CFBasicHashFindBucket + 1572 frame #4: 0x01f09ad5 CoreFoundation`CFDictionaryGetValue + 133 frame #5: 0x0088cde8 CoreData`-[NSPersistentStoreCache incrementRefCountForObjectID:] + 40 frame #6: 0x0088cd74 CoreData`-[NSSQLCore managedObjectContextDidRegisterObjectsWithIDs:] + 228 frame #7: 0x009528aa CoreData`-[NSPersistentStoreCoordinator(_NSInternalMethods) _informAffectedStoresOfInterestByChildContextInObjectsWithObjectIDs:withSelector:] + 122 frame #8: 0x0088cc7f CoreData`-[NSPersistentStoreCoordinator(_NSInternalMethods) managedObjectContextDidRegisterObjectsWithIDs:] + 47 frame #9: 0x008bd9e9 CoreData`__-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:]_block_invoke_1 + 73 frame #10: 0x008bce41 CoreData`internalBlockToNSManagedObjectContextPerform + 17 frame #11: 0x01de5953 libdispatch.dylib`_dispatch_barrier_sync_f_invoke + 61 frame #12: 0x01de5e00 libdispatch.dylib`dispatch_barrier_sync_f + 62 frame #13: 0x008bcde5 CoreData`_perform + 117 frame #14: 0x008bd999 CoreData`-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:] + 73 frame #15: 0x008bd9e9 CoreData`__-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:]_block_invoke_1 + 73 frame #16: 0x008bcdc4 CoreData`_perform + 84 frame #17: 0x008bd999 CoreData`-[NSManagedObjectContext(_NestedContextSupport) managedObjectContextDidRegisterObjectsWithIDs:] + 73 frame #18: 0x008ac672 CoreData`-[NSManagedObjectContext(_NSInternalAdditions) _informParentStore:ofInterestInObjects:] + 274 frame #19: 0x008991e8 CoreData`-[NSManagedObjectContext save:] + 536 frame #20: 0x000a06fc MyApp`__53-[DPLNotesViewController editRatingForIndexPath:new:]_block_invoke(.block_descriptor=0xbfffe260) + 1836 at DPLNotesViewController.m:270 frame #21: 0x008bcaf3 CoreData`developerSubmittedBlockToNSManagedObjectContextPerform + 99 frame #22: 0x01de5953 libdispatch.dylib`_dispatch_barrier_sync_f_invoke + 61 frame #23: 0x01de5e00 libdispatch.dylib`dispatch_barrier_sync_f + 62 frame #24: 0x008bca48 CoreData`-[NSManagedObjectContext performBlockAndWait:] + 136 frame #25: 0x0009fe61 MyApp`-[DPLNotesViewController editRatingForIndexPath:new:](self=0x0a367eb0, _cmd=0x0010fb59, indexPath=0x083f9200, new='\x01') + 465 at DPLNotesViewController.m:251 frame #26: 0x0009f786 MyApp`-[DPLNotesViewController tableView:didSelectRowAtIndexPath:](self=0x0a367eb0, _cmd=0x02ba0ff6, tableView=0x08c69a00, indexPath=0x083f9200) + 150 at DPLNotesViewController.m:195 frame #27: 0x00bad71d UIKit`-[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1164 frame #28: 0x00bad952 UIKit`-[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 201 frame #29: 0x0143586d Foundation`__NSFireDelayedPerform + 389 frame #30: 0x01fc6966 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 22 frame #31: 0x01fc6407 CoreFoundation`__CFRunLoopDoTimer + 551 frame #32: 0x01f297c0 CoreFoundation`__CFRunLoopRun + 1888 frame #33: 0x01f28db4 CoreFoundation`CFRunLoopRunSpecific + 212 frame #34: 0x01f28ccb CoreFoundation`CFRunLoopRunInMode + 123 frame #35: 0x021ac879 GraphicsServices`GSEventRunModal + 207 frame #36: 0x021ac93e GraphicsServices`GSEventRun + 114 frame #37: 0x00b1da9b UIKit`UIApplicationMain + 1175 ``` What else can I try? Help!

Original source

Related problems