NSPersistentStoreCoordinator在读取特定NSManagedProperty后释放NSManagedObject时抛出EXC_BAD_ACCESS

错误说明

我有一个使用核心数据(由SQLite支持)和以下NSManagedObject子类本地存储的一些应用程序

 import CoreData @objc(ScoutingEventData) class ScoutingEventData: NSManagedObject { @NSManaged var id: String? @NSManaged var type: String? @NSManaged var entityId: String? @NSManaged var oldStateJson: NSData? @NSManaged var newStateJson: NSData? @NSManaged var eventDate: NSDate? func toInsertEvent() throws -> ScoutingEvent.Insert { guard let id = id else { fatalError("events should have an event id") } guard let data = newStateJson else { fatalError("insert event should have newStateJson stored") } // If I uncomment this line, the error goes away. // Somehow by ensuring that data never gets deallocated, the error never occurs. // globallllll = data return ScoutingEvent.Insert(id: id, entity: try ScoutingEntity.from(data)) } } // debugging var to prevent data from being deallocated var globallllll: NSData? 

正如上面的代码片段中提到的,如果我允许从newStateJson属性中读取的值被释放,就会发生错误。

我收到的错误来自后台线程:

访问不好

如果我在诊断工具中启用僵尸,我可以取而代之

在这里输入图像说明

如果僵尸已启用,我还会在控制台中收到以下消息:

2016-11-18 16:26:13.773 ScoutingData_Example [51750:4716636] *** – [CFData发布]:发送到释放实例的消息0x7f8c4eb10ae0

和下面的堆栈跟踪:

在这里输入图像说明


我迄今为止所尝试的

我试图存储NSManagedObjectContext用于获取这个数据在一个静态variables,以确保上下文永远不会被释放,但没有效果。

我曾尝试转换NSData? 属性来String? 属性,并将数据存储为Base64编码的string而不是二进制数据(并且还更新了支持模型),但这也没有效果。 错误仍然存​​在。

我已经尝试过注释读取属性的代码,并且错误消失了,但这显然不是一个可接受的解决scheme。

我已经试过将它存储在全局variables中,以防止它被释放,错误消失,但这也不是一个有效的解决scheme。

我已经尝试注释掉所有使用该值的代码,而只是将值打印到控制台,并且错误仍然存​​在。 这使我相信,随时获取财产,然后再解除分配的行为,是造成这种错误的条件。


我很难过。 看起来很奇怪,在阅读完数据之后,我应该怎样处理这些数据,而在后台线程释放任何东西时,看起来尤其奇怪。

更奇怪的是,这个属性似乎是特定的。 例如,我读取newDataJson属性的行上方的id属性不会导致任何问题。 你可能会认为这是不同的,因为id是一个string,而不是NSData,但我试图将我的NSData属性转换为一个string属性,而它仍然没有改变错误。

任何想法将不胜感激。 谢谢。

编辑

不知道这是否会有所帮助,但这是我的模型架构

在这里输入图像说明

给该属性一个不以new开始的名称。 我有类似的问题,并不得不重新命名我的财产像像theNewState 。 我认为new前缀具有特殊的含义和混淆ARC内存pipe理。

编辑:引用Apple ARC发行说明 ,请参阅“不能给访问者提供以新名称开头的名称”一节。 所以它实际上是访问者/获取者名称,而不是属性名称本身。