美文网首页
Block底层

Block底层

作者: 吕建雄 | 来源:发表于2021-01-31 08:07 被阅读0次

    Block在开发中是一个使用比较高频的技术实现;给开发带来了很多的便捷性,在使用block的过程中,老生常谈的问题就是block对于外部变量的捕获以及容易造成循环引用的问题;

    今天分三部分来揭晓下,block对于外部变量的捕获在底层是如何实现的;

    一、对于访问了局部变量的block

    访问局部变量a的block

    对于访问了局部变量的block(栈block),会直接捕获局部变量到block中

    底层会生成一个__main_block_impl_0 的结构体和__main_block_func_0函数(__main_block_impl_0此处的0其实与当前代码中block的数量以及第一个block有关系,比如第一个block就是0,如果第二个block就是1...以此类推)

    其中:

    __main_block_impl_0结构体内部包含:

    1、block_impl结构体

    2、__main_block_desc_0* Desc,

    3、捕获的局部变量(例子中是a)

    4、__main_block_func_0函数(构造函数)会包含一个默认参数(这个参数为当前__main_block_impl_0),在函数中就是使用该参数直接来调用其中的变量

    访问局部变量的block底层

    __main_block_impl_0的构造函数,会将(__main_block_func_0,__main_block_desc_0,捕获的局部变量,flags)作为构造参数,来构造__block_impl对象 ,最终的调用都是使用__block_impl来进行(见上图:__main_block_impl_0函数)

    main_block_func_0

    二:对于访问了全局变量的block(global block)

    访问全局变量b的block

    并不捕获变量,而是__main_block_func_1中直接使用

    __main_block_impl_1

    三、访问使用__block修饰的局部变量

    访问__block修饰变量的block

    对于使用了__block修饰的局部变量,底层会生成一个__Block_byref_*这样一个结构体(其实也是一个对象,因为有isa),对于__block修饰的变量,直接捕获的是生成的__Block_byref对象

    __Block_byref_c结构体

    结构体中包含:isa, __forwarding指针,局部变量c,以及__flags,__size

    __main_block_impl_2

    在__main_block_impl_2中 ,对于__block修饰的变量,直接捕获的是生成的__Block_byref对象

    __main_block_func_2

    在__main_block_func_2中,对于__block修饰的变量,直接使用的是生成的__Block_byref对象,然后调用该对象的__forwarding来进行修改

    实际上对于__block修改的变量,使用的值址传递;

    block调用:

    block调用

    调用block的时候,使用的是__block_impl的FuncPtr调用函数;底层会有一个默认参数,将__block_impl(也即是当前block)传递进去

    调用底层实现

    代码实现地址

    下载代码,然后进入到mian.m路径下,执行如下命令,可直接生成编译后的.cpp文件

    clang -rewrite-objc -fobjc-arc -fobjc-runtime=ios-14.0.0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.3.sdk  main.m

    注意:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator14.3.sdk 需要替换为自己本地的SDK路径

    相关文章

      网友评论

          本文标题:Block底层

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