面试复习-Block

作者: 云无心 | 来源:发表于2021-04-21 10:36 被阅读0次

    本质

    1. block本质是一个oc对象,内部有isa指针
    2. block是封装了函数和函数调用环境的oc对象
    3. block内部有 isa,flag,funcptr,descriptor( size copy dispose函数),捕获的变量 variavles

    类型

    1. 未捕获变量 NSConcreteGlobalBlock (NSGlobalBlock)(数据区.data区)
    2. 捕获了auto变量且进行了 copy,NSConcreteMallocBlock (堆)
    3. 捕获了auto变量且未进行 copy,NSConcreteStackBlock(栈)

    捕获变量

    1. 对于 auto 值捕获
    2. 对于 static 指针捕获
    3. 对于全局变量 直接访问

    捕获变量内存管理

    1. block在栈上,不回产生强引用
    2. block被copy到堆上
    • 会调用block内部 copy 函数,内部调用 _Block_object_assign函数
    • _Block_object_assign函数会根据auto变量外部的修饰符,作出对应的操作,形成 retain 引用 或者 weak 引用
    • _Block_object_assign也会对__block修饰对象强引用
    1. block从堆上移除
    • 调用block内部 dispose 函数,内部调用 _Block_object_dispose函数
    • _Block_object_dispose函数会释放引用的auto变量
      -- _Block_object_assign也会对__block修饰对象释放

    Block的copy

    1. ARC下,很多情况会自动进行block的copy,进行内存管理
    • block作为函数返回值
    • cocoa API中包含 usingBlock的方法参数
    • 作为GCD API
    1. ARC 使用strong 和 copy对block进行修饰皆可

    _ _block修饰符

    1. __block为了解决内部无法修改 auto变量
    2. __block修饰的变量会被包装成对象
    • 对象内有 isa,forwarding,size,age(变量)
    1. 当block在栈上,不会对__block产生强引用
    2. _Block_object_assign会对__block形成强引用,同理 _Block_object_dispose一样
    3. MRC下,不会对 __block修饰对象reatin

    _ _block的 _ _ forwarding

    1. 栈内部的block的 forwarding指向自己
    2. 当copy到堆上后,栈上的forwarding指向堆上的block,堆上block指向自己,这样能保证不管栈还是堆,访问的变量都是同一份

    解决循环引用

    1. ARC
    • __weak (__unsafe_unretained不推荐)
    • __block (需要调用block且在block内部self=nil)
    1. MRC
    • __unsafe_unretained
    • __block

    hook block

    1. https://blog.csdn.net/weixin_34381666/article/details/87951992
    2. https://juejin.cn/post/6844903776839532552
    3. https://blog.csdn.net/qq_32792839/article/details/99842250
    4. https://juejin.cn/post/6844903776839532552

    相关文章

      网友评论

        本文标题:面试复习-Block

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