DisplayLink内存泄漏

昨天在查某一个核心类的时候,发现有明显的内存泄漏,写法如下

private lazy var displayLink: CADisplayLink = {
        let displayLink = CADisplayLink(target: self, selector: #selector(refreshUI))
        displayLink.preferredFramesPerSecond = 30
        displayLink.add(to: .main, forMode: .common)
        displayLink.isPaused = true
        return displayLink
    }()
...
// 在某个地方调用懒加载
displayLink.isPaused = true

之后就没有再处理了,这明显是不对的,我先做了如下处理

// 在核心类置空之前,手动调用
displayLink.invalidate()

invalidate与NSTimer的作用是基本一样的,描述是
/* Removes the object from all runloop modes (releasing the receiver if
* it has been implicitly retained) and releases the 'target' object. */
从runloop移除,并释放target对象。从描述上看,本应就结束了,既没有在runloop中也没有持有target对象。然后实际上仍然持有target。
经过实验后发现因为displayLink是用的懒加载的block创建的,block引用了self,这引起的循环引用
因此此处我做了如下修改

    private lazy var displayLink: CADisplayLink = { [unowned self] in
        let displayLink = CADisplayLink(target: self, selector: #selector(refreshUI))
        displayLink.preferredFramesPerSecond = 30
        displayLink.add(to: .main, forMode: .common)
        displayLink.isPaused = true
        return displayLink
    }()

捕获列表中添加unowned self,经测试,target不在被强持有。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容