Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CoreData error with EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

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.

like image 784
ArdenDev Avatar asked Oct 27 '25 08:10

ArdenDev


1 Answers

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.

like image 116
Tom Harrington Avatar answered Oct 29 '25 22:10

Tom Harrington



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!