美文网首页swiftiOS DeveloperiOS
关于weak-strong Dance的一些思考

关于weak-strong Dance的一些思考

作者: samingzhong | 来源:发表于2016-04-04 12:09 被阅读109次

    首先需要说明清楚的是,并不是遇到block捕获引用就得用上weak-strong Dance,只有在出现循环引用的情况下才需要考虑这种做法。【一般在block与目标对象有直接引用关系时很有可能引起循环引用,block与目标对象有间接的相互引用关系也会有可能引起循环引用】

    ARC模式下,block会对block内部引用的外部对象进行强引用,如果block本身就是所引用对象里的实例变量,那么会导致循环引用-内存泄漏。
    解决的办法之一:在block里把关联对象释放(指针置nil)。但此法风格过硬!

    解法二:对引起循环引用的目标对象在block前,新建一个__weak类型的指针引用
    ,然后把__weak类型的指针穿进block,即可避免循环引用。但此法会导致block执行前,目标对象会被释放,从而无法继续后面操作。故【一般不推荐此法】,但好多人会这么用!循环引用的问题却是不会出现,但同时也引入了新的问题就是,对象释放了,没法做太多的活。

    解法三:weak-strong Dance
    在block外边依旧新增一个weak类型指针指向可能导致循环引用的节点对象,然后block内部使用一个strong类型(ARC下变量默认的修饰符)的指针指向这个weak类型指针。会产生这么一个现象:使目标对象retain。但由于block没有直接使目标对象retain,而是其内部的函数执行的时候局部变量做的retain,执行完了之后,这个局部变量就销毁了。也就是目标对象也会release,如果其retainCount为0,就会被当即回收。【此为解决循环引用的正确姿势】

    思考:由于在block内部使用局部strong类型的指针指向目标对象,确实会使其retian,但是block里边这段代码要是在执行前,目标对象就被释放了,也是同样导致后续操作的执行失效。【这种思考是有误的】
    因为对目标对象的retain动作发生在拷贝block到堆区的时候,内存里声明了strong类型的局部变量指向目标对象的时候,就会使之retain。不会导致循环引用就是因为block执行完毕之后(也就是block内部的函数指针指向的函数(block对{}的封装)执行后,局部变量超出作用域,使指向的目标对象release

    相关文章

      网友评论

      • iOS_愛OS:解决的办法之一:在block里把关联对象释放(指针置nil)。但此法风格过硬!

        是指在在block即将执行结束的时候把对象置为nil么?
        samingzhong:@iOS_愛OS 嗯,这样会使目标对象release。
      • iOS_愛OS:block与目标对象有间接的相互引用关系也会有可能引起循环引用】
        这句话表示看不懂,不知道是那种可能下会引起循环引用
        iOS_愛OS:@iOS_愛OS 谢谢哈,这样我就清楚啦
        samingzhong:@iOS_愛OS 当对象的强引用关系比较复杂时,可能一眼看不出循环引用,但确实发生了。如:a强引用b,b强引用c,c强引用a……
      • iOS_愛OS:一般在block与目标对象有直接引用关系时很有可能引起循环引用
        我对这句话的理解是,当block为目标对象得属性是会引起循环引用,不知道对不对!
        samingzhong:@iOS_愛OS 具体得看对象之间完整的引用关系

      本文标题:关于weak-strong Dance的一些思考

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