When I turn on the Concurrency debug switch 'com.apple.CoreData.ConcurrencyDebug 1' to track all concurrency issues with CoreData, I keep getting a crash when calling insertingNewObjectForEntityForName.
The message Xcode shows me is EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0). Here's my code
Here's my implementation of managedObjectContext
- (NSManagedObjectContext *)managedObjectContext
{
if (_managedObjectContext != nil) {
return _managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return _managedObjectContext;
}
and here's the implementation of [self privateContext]
-(NSManagedObjectContext *)privateContext
{
NSManagedObjectContext *pvtContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
pvtContext.parentContext = [CoreDataMgr sharedInstance].managedObjectContext;
return pvtContext;
}
Scenario 1: executing on main thread - does not crash
NSManagedObjectContext *mainContext = [CoreDataMgr sharedInstance].managedObjectContext;
CDPayments* cdPayment = [NSEntityDescription insertNewObjectForEntityForName:PAYMENTS_TABLE inManagedObjectContext:mainContext];
Scenario 2: Executing on background thread - CRASHES !!
NSManagedObjectContext *pvtContext = [self privateContext];
CDPayments* cdPayment = [NSEntityDescription insertNewObjectForEntityForName:PAYMENTS_TABLE pvtContext];
I'm really not clear why executing this on the background thread with a private context is crashing ...
I am using Xcode 8 against iOS9 SDK and the above code is called when saving a payment object.
It's because you're doing Core Data concurrency wrong. When you use NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType, you must wrap your Core Data code in calls to perform() or performAndWait(). If you don't, your code is violating concurrency rules and this crash is completely expected.
The only exception to this is if you use NSMainQueueConcurrencyType and you are certain that the code is running on the main queue, you can make the Core Data calls directly, without wrapping them in blocks.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With