也许我见过的最奇怪的EXC_BAD_ACCESS Swift生成

时间:2017-01-08 02:52:17

标签: swift exc-bad-access nszombie

我有一组构成装饰器模式的类,以便我可以进行一些分层缓存。我有一个抽象类,它提供了图像的核心处理,并包含许多可覆盖的函数,其中实现可以添加它们各自的处理。

保存图像时,我有以下代码:

func cacheImage(_ key:String, image:UIImage?) {
    if let image = image {
        saveImage(key, image:image)
    } else {
        deleteImage(key)
    }
    backingCache?.cacheImage(key, image:image)
}

func saveImage(_ key:String, image:UIImage) {}

func deleteImage(_ key:String) {}

这是奇怪的地方。编译为Release时,此代码将生成EXC_BAD_ACCESS。使用Zombies跟踪它会显示消息在被解除分配后发送到UIImage实例。

如果我尝试通过使用Debug配置进行编译来获取更多信息,则EXC_BAD_ACCESS将停止发生。使调试非常困难。

我发现如果我添加print(...)这样的语句:

func deleteImage(_ key:String) {
    print("Abstract delete image")
}

EXC_BAD_ACCESS消失了。

我目前的理论是,如果没有print(...),Swift会积极地取消分配图像实例。我还记得读过有关Debug延迟ARC垃圾收集的内容,这可以解释为什么在调试中不会发生EXC_BAD_ACCESS。

我现在还发现将方法签名更改为:

open func deleteImage(_ key:String) {}

同时删除EXC_BAD_ACCESS。

任何人都可以更详细地解释EXC_BAD_ACCESS僵尸发生的原因吗?我不明白为什么一开始。

0 个答案:

没有答案