Perhaps the weirdest EXC_BAD_ACCESS I've seen Swift generate

放肆的年华 提交于 2019-12-12 18:23:27

问题


I have a set of classes forming a decorator pattern so that I can do some layered caching. I have an abstract class which provides the core processing of images and contains a number of overridable functions where implementations can add their individual processing.

When saving an image I have the following code:

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) {}

This is where it gets weird. When compiled for Release, this code will generate an EXC_BAD_ACCESS. Tracing it with Zombies on shows messages being sent to UIImage instances after they have been deallocated.

If I attempt to get more information by compiling with the Debug configuration, the EXC_BAD_ACCESS stop occurring. Making it very difficult to debug.

I've found that if I add a print(...) statements like this:

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

the EXC_BAD_ACCESS goes away.

My current theory is that without the print(...), Swift is aggressively de-allocing the image instances. I also remember reading something about Debug delaying ARC's garbage collection which would explain why the EXC_BAD_ACCESS doesn't occur in debug.

I've also now found that changing the method signature to:

open func deleteImage(_ key:String) {}

Also removes the EXC_BAD_ACCESS.

Can anyone give a more detailed explanation of why the EXC_BAD_ACCESS zombies are occurring? I can't see why in the first place.

来源:https://stackoverflow.com/questions/41528974/perhaps-the-weirdest-exc-bad-access-ive-seen-swift-generate

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!