美文网首页
__weak、__block和__strong修饰符

__weak、__block和__strong修饰符

作者: zzcz_cc | 来源:发表于2017-03-22 17:09 被阅读0次

    __weak本身是可以避免循环引用的问题的,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong 的变量来指向 Obj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题。
    __block 本身无法避免循环引用的问题,但是我们可以通过在 block 内部手动把 blockObj 赋值为 nil 的方式来避免循环引用的问题。另外一点就是__block 修饰的变量在 block 内外都是唯一的,要注意这个特性可能带来的隐患。
    总结:
    1 . 在MRC(手动内存计数)模式下,__block修饰,可以避免循环引用;ARC(自动内存计数)模式下,__block修饰,还是会引起循环引用问题;
    2 . __block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型;
    3 . __weak只能在ARC模式下使用,也只能修饰对象,不能修饰基本数据类型;
    4 . __block对象可以在block中被重新赋值,__weak不可以;

    API Reference对__block变量修饰符的解释,大概意思:
    1.__block对象在block中是可以被修改、重新赋值的。
    2.__block对象在block中不会被block强引用一次,从而不会出现循环引用问题。

    API Reference对__weak变量修饰符的解释,大概意思:
    使用了__weak修饰符的对象,作用等同于定义为weak的property。自然不会导致循环引用问题,因为苹果文档已经说的很清楚,当原对象没有任何强引用的时候,弱引用指针也会被设置为nil。
    因此,__block和__weak修饰符的区别其实是挺明显的:
    1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。
    2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。
    3.__block对象可以在block中被重新赋值,__weak不可以。

    Tips:__unsafe_unretained修饰符可以被视为iOS SDK 4.3以前版本的__weak的替代品,不过不会被自动置空为nil。所以尽可能不要使用这个修饰符。
    Block的生命周期管理非常的微妙,与ARC混在一起后,更加复杂。
      当Block延stack向上(up)传递的时候,直接返回,编译器会添加[[ copy] autorelease]代码。
      当Block延stack向下传递给需要retain的容器的时候,需要显式的调用[^{} copy]方法。
      在ARC下,__block修改的NSObject指针依然会被retain。
    在ARC下,一个block内引用一个对象的实例变量后,self会被retain,所以极易造成strong reference cycle,可以通过__weak指针来避免这种情形,因为ARC不会为__weak指针retain。

    相关文章

      网友评论

          本文标题:__weak、__block和__strong修饰符

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