【问题标题】:Core Data strange crashCore Data 奇怪的崩溃
【发布时间】:2016-10-27 00:49:11
【问题描述】:

我使用这样的核心数据:

- (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:> 在枚举时发生了变异。 怎么了?如何在多线程中使用核心数据?

【问题讨论】:

    标签: ios objective-c multithreading core-data


    【解决方案1】:

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

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

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

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

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

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

    一切都取决于您想做什么以及您要达到什么目标。在更广泛的方面,我建议使用亲子环境。它很健壮,可以解决您的 Core Data 多线程问题。

    编辑-

    请查看this 答案,了解核心数据中父子上下文的正确实现。

    【讨论】:

    • 父子上下文:请帮忙,怎么做
    • for(NSManageObject *obj in someArray){ [context deleteObject:someArray];在这个例子中,我们需要使用子上下文吗?
    • 如果我在删除后保存 [self.managedObjectContext save:&error],应用程序停止崩溃?
    • 更好的解决方案是将要删除的所有对象保存在一个数组中,然后一次删除所有对象。
    • 我有另一个崩溃:当我更改 nsmanagedobject 属性时,EXC_BAD_ACCESS KERN_INVALID_ADDRESS。这里有什么问题?
    【解决方案2】:
    *- (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 
    

    【讨论】:

      猜你喜欢
      • 2012-05-02
      • 2013-11-16
      • 2019-03-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-01
      • 2023-02-02
      相关资源
      最近更新 更多