尝试访问托管对象属性时的EXC_BAD_ACCESS

时间:2013-03-17 19:48:03

标签: objective-c cocoa-touch cocoa core-data

我在处理Core Data +并发/嵌套MOC方面遇到了一些麻烦(不确定哪一个我遇到了= P的问题)。

我有一个方法,我传入一个托管对象ID(我检查它是永久的),并且该方法有一个子托管对象上下文,该上下文仅限于某个队列。我可以通过[managedObjectContext objectWithID:moID]从子管理对象上下文中检索对象,但是当我尝试访问它的任何属性时(托管对象仍然是一个错误),我得到EXC_BAD_ACCESS,堆栈跟踪显示{ {1}}和_svfk_1

我知道如果没有示例代码,很难弄清楚问题是什么,但我希望有人可以解释可能的原因。谢谢。 =)

编辑:我尝试使用objc_msgSend代替existingObjectWithID:error:,正如Tom Harrington建议的那样,现在它有时可以正常工作,但在其他时候不起作用。我在objectWithID:遇到EXC_BAD_ACCESS崩溃。我怀疑这可能是同步问题。如果我在一个上下文中编辑某些内容并在我的子上下文中编辑其他内容时保存,那会导致问题吗?

编辑2:我弄清楚为什么existingObjectWithID:error:有时会工作,但并非总是如此。托管对象ID确实是一个临时ID(不应mergeChangesFromContextDidSaveNotification:将其转换为永久ID?),因此我必须在传递ID之前调用mergeChangesFromContextDidSaveNotification:。但是我有时会在子环境obtainPermanentIDsForObjects:error:中遇到崩溃。可能的原因是什么?感谢。

编辑3:这是我的MOC层次结构的样子。

mergeChangesFromContextDidSaveNotification:

我正在从使用Child MOC(在另一个队列中)的主队列调用一个方法来插入和更新一些托管对象,同时,我在Persistent Store MOC中插入和更新托管对象。托管对象也可以同时更新,删除和插入主队列MOC。我将持久存储协调器中的任何更改合并到主队列MOC和子MOC。

还有一些问题:保存MOC会自动合并吗?如果有MOC的待处理合并请求,并且在处理合并请求之前保存,是否会导致问题?

编辑4:以下是我初始化Child MOC的方法。

   Persistent Store Coordinator
                |
      Persistent Store MOC
         /            \
Main Queue MOC   Child MOC (confinement)

顺便说一句,我注意到当通知包含已删除的对象时,合并只会崩溃(使用dispatch_sync(_searchQueue, ^{ _searchManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType]; [_searchManagedObjectContext setParentContext:_persistentStoreManagedObjectContext]; [_searchManagedObjectContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy]; }); )。

2 个答案:

答案 0 :(得分:1)

看起来你还在努力工作。对于您的孩子MOC,因为它在串行队列中,使用NSPrivateQueueConcurrencyType,并将其父级设置为您的主MOC。

NSConfinementConcurrencyType适用于旧版配置。

答案 1 :(得分:0)

我找到了解决办法。在每次保存之前,我都会[moc obtainPermanentIDsForObjects:[[moc insertedObjects] allObjects] error:&error]。现在我不再遭遇崩溃了。

对于究竟发生了什么,我仍然有点模糊,但这是我的理解。保存新插入的对象时,只有在连接到持久性存储协调器的MOC保存时,才会为它们分配永久ID。现在,mergeChangesFromContextDidSaveNotification:要么将永久ID传播回来(正如我预期的那样),其他一些操作恰好发生在合并之前,或者某处有一个Apple bug。无论如何,事先获得永久性ID解决了这个问题。

TL; DR Core Data +并发很难。