在读取特定的NSManagedProperty后释放NSManagedObject时,NSPersistentStoreCoordinator抛出EXC_BAD_ACCESS [英] NSPersistentStoreCoordinator throws EXC_BAD_ACCESS when deallocating an NSManagedObject after reading a specific NSManagedProperty

查看:107
本文介绍了在读取特定的NSManagedProperty后释放NSManagedObject时,NSPersistentStoreCoordinator抛出EXC_BAD_ACCESS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an app with some data stored locally using core data (backed by SQLite) and the following NSManagedObject subclass

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 属性将被释放。

As mentioned in the comment in the snippet above, there is an error occurring if I allow the value I read out of the newStateJson property to be deallocated.

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

The error I receive comes from a background thread:

如果我在诊断工具中启用了僵尸,我会得到它

If I enable zombies in the diagnostic tool, I get this instead

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

And I also get the following message in the console if zombies are enabled:


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

2016-11-18 16:26:13.773 ScoutingData_Example[51750:4716636] *** -[CFData release]: message sent to deallocated instance 0x7f8c4eb10ae0

以及以下堆栈跟踪:

我已经尝试过将 NSManagedObjectContext 存储到用于获取此数据的静态变量中,以确保上下文永远不会被释放,但这没有任何作用。

I have tried storing the NSManagedObjectContext which was used to fetch this data in a static variable to ensure that the context never gets deallocated, but that had no effect.

我尝试将 NSData?属性转换为 String?属性,并将数据存储为Base64编码字符串而不是二进制数据(还更新了支持模型),但这也不起作用。错误仍然存​​在。

I have tried converting the NSData? properties to String? properties, and storing the data as a Base64 encoded string instead of binary data (and also updating the backing model), but that had no effect either. The error still persisted.

我尝试注释掉读取该属性的代码,但错误消失了,但这显然不是可接受的解决方案。

I have tried commenting out the code that reads the property, and the error dissappeared, but that is obviously not an acceptable solution.

我尝试在读取值后将其存储在全局变量中,以防止将其释放,并且错误消失,但这并不是有效的解决方案。

I have tried storing the value in a global variable after reading it, to prevent it from ever being deallocated, and the error dissappeared, but that is also not a valid solution.

我尝试注释掉所有使用值的代码,而只将值打印到控制台,错误仍然存​​在。这使我相信完全访问该属性然后稍后对其进行分配的行为是造成此错误的条件。

I have tried commenting out all the code that uses the value, and instead only printing the value to the console, and the error persisted. This leads me to believe that the act of accessing the property at all, and then deallocating it later, is what creates the conditions for this error.

我很沮丧。在读取数据后对数据进行处理应该很重要,这真的很奇怪,而且在后台线程被释放后,任何事情都会在后台线程上发生。

I am pretty stumped. It seems really odd that it should matter what I do with the data after I read it, and it seems especially odd that anything happens on a background thread when it gets deallocated.

还有更多奇怪的是,这似乎特定于这一特性。例如,我在读取newDataJson属性的行上方读取的id属性不会造成任何问题。您可能会认为这是不同的,因为id是一个字符串,而不是NSData,但是我尝试将NSData属性转换为字符串属性,但是它仍然没有更改错误。

What's even more odd is that it seems specific to this one property. For instance, the id property which I read right above the line that reads the newDataJson property doesn't cause any problems. You might think thats different because the id is a string, not NSData, but I tried converting my NSData property to a string property instead, and it still didn't change the error.

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

Any ideas would be greatly appreciated. Thanks.

不确定是否有帮助,但这是我的模型架构

Not sure if this will help, but here's my model schema

推荐答案

为属性指定一个以<$ c开头的名称$ c>新。我遇到了类似的问题,不得不将我的财产重命名为 theNewState 。我认为 new 前缀具有特殊含义,并且会混淆ARC内存管理。

Give the property a name that doesn't start with new. I have had similar problems and had to rename my property to something like theNewState. I think the new prefix has special meaning and confuses ARC memory management.

编辑:引用 Apple ARC发行说明,请参见不能给访问者一个以new开头的名称。因此,它实际上是访问者/获取者名称,而不是属性名称本身。

reference Apple ARC release notes, see the section saying "You cannot give an accessor a name that begins with new." So it's actually the accessor/getter name, not the property name itself.

这篇关于在读取特定的NSManagedProperty后释放NSManagedObject时,NSPersistentStoreCoordinator抛出EXC_BAD_ACCESS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆