EXC_BAD_INSTRUCTION出现CoreData错误(代码= EXC_I386_INVOP,子代码= 0x0)

时间:2016-11-09 05:40:29

标签: ios core-data iphonecoredatarecipes

当我打开Concurrency调试开关时,com.apple.CoreData.ConcurrencyDebug 1'为了跟踪CoreData的所有并发问题,我在调用insertedNewObjectForEntityForName时不断遇到崩溃。

Xcode显示的消息是EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)。这是我的代码

这是我对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;
}

这里是[self privateContext]

的实现
-(NSManagedObjectContext *)privateContext
{
    NSManagedObjectContext *pvtContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
pvtContext.parentContext = [CoreDataMgr sharedInstance].managedObjectContext;
return pvtContext;
}

场景1:在主线程上执行 - 不会崩溃

NSManagedObjectContext *mainContext = [CoreDataMgr sharedInstance].managedObjectContext;
CDPayments* cdPayment = [NSEntityDescription insertNewObjectForEntityForName:PAYMENTS_TABLE inManagedObjectContext:mainContext];

场景2:在后台线程上执行 - CRASHES !!

NSManagedObjectContext *pvtContext = [self privateContext];
CDPayments* cdPayment = [NSEntityDescription insertNewObjectForEntityForName:PAYMENTS_TABLE pvtContext];

我真的不清楚为什么在私有上下文的后台线程上执行此操作会崩溃......

我正在使用Xcode 8对抗iOS9 SDK,并在保存付款对象时调用上述代码。

1 个答案:

答案 0 :(得分:3)

这是因为您在核心数据并发性方面做错了。当您使用NSPrivateQueueConcurrencyTypeNSMainQueueConcurrencyType时,必须将您的核心数据代码打包到perform()performAndWait()。如果你不这样做,你的代码就违反了并发规则,完全可以预料到这种崩溃。

唯一的例外是如果你使用NSMainQueueConcurrencyType并且某些代码在主队列上运行,你可以直接进行核心数据调用,而不必包装它们在街区。