核心数据奇怪崩溃

时间:2016-06-24 11:48:18

标签: ios objective-c multithreading core-data

我使用这样的核心数据:

- (NSManagedObjectContext *)managedObjectContext {
@synchronized(self) {
    if (_managedObjectContext != nil) {
        return _managedObjectContext;
    }

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
    if (coordinator != nil) {
        _managedObjectContext = [NSManagedObjectContext new];
        [_managedObjectContext setPersistentStoreCoordinator:coordinator];
    }
}

return _managedObjectContext;
}

- (NSManagedObjectModel *)managedObjectModel {
@synchronized(self) {
    if (_managedObjectModel != nil) {
        return _managedObjectModel;
    }
    NSString *path = [[NSBundle mainBundle] pathForResource:@"DB" ofType:@"momd"];
    if (path) {
        NSURL *momURL = [NSURL fileURLWithPath:path];
        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
    }
}

return _managedObjectModel;
}

但有时我会崩溃:  集合< __ NSCFSet:0x14c5bffdq>在被列举时被突变。 怎么了?如何使用多线程核心数据?

2 个答案:

答案 0 :(得分:0)

当您在for循环或while循环中变异或更改核心数据实体时,会发生此崩溃。像这样的东西

    for(NSManageObject *obj in someArray){
        [context deleteObject:someArray];
   }

由于崩溃,您可能必须更改您想要实现的目标的逻辑。

现在,如果您想在后台模式下执行Core数据,有一些方法可以做到这一点。

  • 亲子上下文就是其中之一,您可以在其中创建子上下文并完成performBlock中的所有工作并推送保存更改,因为它会自动推送更改回父MOC。

  • 异步单例队列中操作,但在主队列中执行更改或saveContext。您还可以使用NSOperationQueue交换队列,并创建一个单例。 这样,您可以在后台执行Core Data操作,因为您不要冻结UI。

一切都取决于你想做什么以及你想要达到的目标。在更广泛的方面,我建议去寻找亲子背景。它非常强大,可以解决您的Core Data多线程问题。

编辑 -

请查看this答案,了解核心数据中父子环境的正确实施。

答案 1 :(得分:0)

*- (NSManagedObjectContext *)managedObjectContext
{
    DDLogTrace();
    if (__managedObjectContext != nil) {
        return __managedObjectContext;
    }

    dispatch_block_t initBlock = ^{
        NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
        if (coordinator != nil) {
            __managedObjectContext = [[NSManagedObjectContext alloc] init];


        }
    };

    if ([NSThread isMainThread]) {
        initBlock();
    }else{
        dispatch_sync(dispatch_get_main_queue(), initBlock);
    }

    return __managedObjectContext;
}*


Try this , many time thread swich and   NSManagedObjectContext create in secondary or background thread .
NSManagedObjectContext always execute in main thread