Swift闭包循环引用解决方法

闭包中的循环引用可通过weak与unowned解决

weak引用时:必须是可选类型的var,因为实例销毁后,ARC会自动将弱引用设置为nil。此时不会触发属性观察器(willSet/didSet)

unowned引用时: 不会产生强引用,实例销毁后仍然存储着实例的内存地址。如果在实例销毁后继续访问无主引用,会产生运行时错误(野指针)

class Person {

    var fn: (() -> ())?

    func run() {

        print("Person run")

        fn?()

    }

    deinit{

        print("Person deinit")

    }

}

当另一个页面调用闭包时,以下代码会造成循环引用,不会来到deinit方法

    var id = 1

    func test() {

        p.fn = { () in

            print("调用了person fn",self.id)

        }

        p.run()

    }

一、使用weak解决循环引用

写法一

写法二

二、使用unowned解决循环引用

写法一

写法二

如果是lazy属性闭包调用,则不用考虑循环引用的问题,因为调用后,闭包的生命周期就结束了

三、weak与unowned的区别

1、使用weak,在闭包中访问外界变量返回可选类型;而unowned则返回原类型

2、在实例销毁后继续访问(unowned)引用,会产生运行时错误(野指针),如下图所示

unowned var up = Person()

    func test() {

        up.run()

    }

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

推荐阅读更多精彩内容