美文网首页Swift编程
【swift tip】[weak self] 在闭包中的使用机制

【swift tip】[weak self] 在闭包中的使用机制

作者: SmartisanBool | 来源:发表于2020-03-21 00:11 被阅读0次

    ​众所周知,闭包(Closures)的使用可以很大的简化我们的代码,也可以让我们更容易的写出更具逻辑性的代码。但如果使用不当就容易产生循环引用,进而产生内存泄漏。我们往往在闭包中使用[weak self]来避免循环引用的产生,但是否所有的闭包都应该使用[weak self]呢,其中又有哪些注意点呢?

    闭包中是否需要使用[weak self]的判断法则

    image

    1.逃逸闭包与非逃逸闭包

    非逃逸闭包:没有赋值于存储变量、立即执行、没有传递给其他闭包;

    逃逸闭包:赋值于存储变量、在未来某个时间点执行、传递给其他闭包;

    2.是否可以接受延迟释放持有闭包的对象

    当闭包中有比较耗时的操作(比如图片处理)或者闭包内操作做了延迟处理,那么如果闭包中包含持有该闭包的对象,将产生该对象延迟释放的问题。比如ViewController中有个闭包执行图片的处理,那么当dismiss后,ViewController有可能在一段时间内不会被回收,直到闭包执行完毕。

    这种问题不会带来内存泄漏,但如果viewcontroller在dismiss后,在一段不可预估的时间内不能被置为nil,往往会带来不可预估的问题,这种情况下,我们需要使用[weak self]。另一方面,如果你要确保闭包里的这段代码必须完整的执行,即使ViewController被dismiss,那么我们可以不使用[weak self]。

    3.基于判断准则的一些示例

    一些高阶函数 或者 立刻执行的Animation,他们属于没有耗时操作的非逃逸闭包,可以不使用[weak self]

    image image

    赋值于某个存储变量,在未来某个时间点执行,他们属于逃逸闭包,需要使用[weak self]

    image

    我们可以将闭包中操作的对象参数当作一个引用传递给闭包,这样也可以在不使用[weak self]的情况下避免内存泄漏

    image

    当我们在闭包中使用GCD的时候,一般也不需要使用[weak self],除非我们把闭包赋值给存储变量并且没有立即执行该闭包。

    image

    和GCD类似,当我们在闭包中执行URLSession的调用时,除非我们把闭包赋值给存储变量并且没有立即执行该闭包。但是由于URLSession任务的执行往往是耗时的操作,这时候我们就会遇到是否需要延时释放对象的问题了。

    image

    直接将A对象的一个方法赋值给B对象闭包属性时,往往忽略[weak self]的使用,不经意间就产生了循环引用:

    image

    其中self持有printingButton,closure又持有self。


    【关注公众号 发现更多精彩】

    相关文章

      网友评论

        本文标题:【swift tip】[weak self] 在闭包中的使用机制

        本文链接:https://www.haomeiwen.com/subject/ocseyhtx.html