美文网首页
block 知识点整理

block 知识点整理

作者: 化二缺 | 来源:发表于2020-05-11 16:22 被阅读0次

    block 本质

    • block 本质上也是一个oc对象,它内部也有一个isa指针
    • block是封装了函数调用以及函数调用环境的OC 对象
    • image.png

    变量捕获

    image.png
    • 为什么 auto 和 static 变量不一样?

    auto 变量是可能被销毁的,所以auto变量是值传递不是指针传递,才不会产生空指针。static 变量 是一直在内存中的,所以用指针去取地址就行了。

    • 为什么局部变量需要捕获,而全局变量不需要?

    因为作用域不同啊。

    • 会不会捕获self,为什么?

    会捕获 ,self 是个局部变量


    self 是个局部变量 因为是参数.png
    • 会不会捕获 _name,为什么?

    会 ,因为_name 相当于 self->_name

    类型

    • block 有3种类型,可以通过调用class方法或者isa指针查看具体类型,最终都是继承自 NSBlock类型
     1.  __NSGlobalBlock__ ( _NSConcreteGlobalBlock )
        //这种意义不大 不如写一个函数
     2. __NSStackBlock__ ( _NSConcreteStackBlock )
      //栈的特点是使用后释放,这样再去调用block 有可能出现混乱 所以使用copy 修饰 升级成堆block
     3. __NSMallocBlock__ ( _NSConcreteMallocBlock )
    //堆block
    
    • block内存地址所在


      image.png
    • block分类型的原因


      image.png
    • 每一种类型的block 调用copy后的结果如下图


      image.png
    • ARC环境下,编译器会依据情况自动将栈上的block复制到堆上

    • 1.作为函数返回值
    • 2.将block赋值给__strong指针的时候
    • 3.block作为Cocoa API 中方法名含有usingBlock的方法参数的时候


      image.png
    • 4.GCD的block (不用写weak 他自己是线程安全的)

    对象类型的auto变量

    • 当block内部访问了对象类型的auto变量时候
    1. 如果block是在栈上,将不会对auto变量产生强引用

    2.如果block被拷贝到堆上

    • 会调用block内部的copy函数
    • copy函数内部会调用 _Block_object_assign函数
    • _Block_object_assign函数会根据auto变量的修饰符(__strong、__weak、__unsafe_unretained)做出相应的操作。类似retain (形成强引用,弱引用)

    3.如果block从堆上移除

    • 会调用block内部的 dispose函数
    • dispose函数内部会调用_Block_object_dispose函数
    • _Block_object_dispose函数会自动释放引用的auto变量,类似于release

    __block 关键字 (能不用就不用)

    • __block的作用
    • __block可以用于解决block内部无法修改auto变量值的问题
    • __block不能修饰全局变量、静态变量(static
    • 编译器会将__block修饰的参数 变成一个对象
    __block包装实例1.png
    __block包装实例2.png
    • __block 细节 :age的地址直接输出 和 __block封装的结构体内部的age结构体地址是一样的,这样做的意义在于屏蔽内部实现。比较符合直觉。

    __weak 问题

    在使用clang转换OC 为C++代码时候,可能会遇到以下问题
    cannot create __weak reference in file using manual reference

    解决方案 : 支持 ARC 指定运行时系统版本
    xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc - fobjc-runtime=iOS-13.0.0 main.m

    __block 内存管理

    • block 是在栈上的时候是不会对 __block 变量产生强引用

    • block 被拷贝到堆的时候

    • 会调用block内部的copy函数
    • copy函数内部会调用 _Block_object_assign函数
    • _Block_object_assign 函数会对 __block变量形成强引用(retain)
    • 这里只是在ARC情况下,MRC不会retain
      image.png
    • block从堆中移除时
    • 会调用block内部的dispose函数
    • dispose函数内部hi调用 _Block_object_dispose函数
    • _Block_object_dispose函数会自己释放引用的 __block变量(release)

    __block的 __forwarding指针

    image.png

    循环引用

    老生常谈 巴拉巴拉。。。

    __unsafe_unretained :不安全弱引用

    __unsafe_unretained__weak的区别

    weak会置空指针
    __unsafe_unretained 不会 ,指针仍然指向,可能会出现野指针问题

    • block在修改 NSMutableArray 需不需要添加__block?

    不需要
    没有修改指针 只是修改了数组内容,所以不用

    相关文章

      网友评论

          本文标题:block 知识点整理

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