Core data EXC_坏访问:基于核心数据队列的并发问题

Core data EXC_坏访问:基于核心数据队列的并发问题,core-data,ios7,ios6,Core Data,Ios7,Ios6,我使用NSPrivateQueueConcurrencyType和NSMainQueueConcurrencyType设置了privateContext,如下所示 [self.mainContext setParentContext:self.privateContext]; 通过此设置,我试图为我的实体MyObject创建一个新的托管对象 代码如下: - (void)createNewObject:(void(^)(MyObject* object))block { [self.pr

我使用
NSPrivateQueueConcurrencyType
NSMainQueueConcurrencyType
设置了
privateContext
,如下所示

[self.mainContext setParentContext:self.privateContext];
通过此设置,我试图为我的实体
MyObject
创建一个新的托管对象

代码如下:

- (void)createNewObject:(void(^)(MyObject* object))block {
    [self.privateContext performBlock:^{
        MyObject *myObj = [NSEntityDescription insertNewObjectForEntityForName:@"MyObject"
                                                               inManagedObjectContext:self.privateContext];
        NSError *error = nil;
        [self.privateContext save:&error];
        if(error) {
            NSLog(@"Error in inserting object: %@", [error localizedDescription]);
        }

        //Get objectId to access it in mainContext
        NSManagedObjectID *objectId = [myObj objectID];
        [self.mainContext performBlock:^{
            if(block)
                block((MyObject*)[self.mainContext objectWithID:objectId]);
        }];
    }];
}
在主线程上调用
,我也在主线程上访问新创建的对象。我签入SQLite存储,可以找到插入表中的这个新对象。我在块中打印这个对象,得到如下结果

<MyObject: 0x140dafc0> (entity: MyObject; id: 0x11cce460 <x-coredata://BE62D8EC-66AA-4608-80F5-88B94CE3EED2/MyObject/p53> ; data: <fault>)

可能不是真正的答案,但太多的评论

  • 您应该始终检查
    保存:
    中的返回,然后检查错误

  • 如果保存MOC时出错,是否确实要继续使用该对象

  • 您应该使用
    existingObjectWithID:error:
    而不是
    objectWithID:
    ,因为如果找不到,前者将返回
    nil
    ,并显示一个
    NSError
    ,说明原因<代码>对象ID:将始终返回对象。。。如果找不到,则视为故障

  • 现在,这并不能解释为什么你会看到iOS6/7中的差异,但我已经从iOS6开始,记不起我在使用MOC层次结构的问题中的所有注释。。。在iOS5和iOS6中有很多这样的人


    因此,我建议使用
    existingObjectWithID:error:
    ,它应该返回一个合理的错误,说明为什么在iOS6中没有检索到该对象。。。也许这会让你马上找到解决办法。。。或者,它可能会为您提供更多信息以添加到问题中。

    +1,
    existingObjectWithID:error
    解决了问题。这个问题似乎有点奇怪,因为调用
    save:
    返回成功而没有错误(在iOS 6和7上)。我还可以看到数据正在被插入到sqlite文件中。但在访问属性时仍然失败,仅在iOS6上。
    [newObject.managedObjectContext refreshObject:newObject mergeChanges:YES]