美文网首页
block(二)-- 底层分析

block(二)-- 底层分析

作者: Ray_lawq | 来源:发表于2019-05-22 23:28 被阅读0次

block(一):https://www.jianshu.com/p/b83574a8ef80
连接上文拿到block 的C++ 文件,内容如下:

那么我们第二章就慢慢分析这个C++文件。

__block 修饰的局部变量变成一个__Blcok_byref_c_0 的结构体,让我们看看这个结构体的实现:

  1. 我们可以很清楚的看到有一个 __frowatding 这个变量,它有什么用呢?
    它是一个桥梁,在Block 内部,先找到这个结构体,通过这个结构体的frowatding成员变量找到外部的局部变量

  2. 那么__frowatding在不同类型的Block指向有什么不同呢:

这样通过__forwarding,无论是在block内部还是外部,不管是堆上还栈,都能访问到同一个__block修饰的变量。

__testBlockA_block_func_0(是Block 内部的方法(代码块))

block 实现方法(__testBlockA_block_impl_0),入参中有2个默认参数(方法): __testBlockA_block_func_0和__main_block_desc_0_DATA

结论:
1. 局部变量不能在block 里边修改值,__block修饰的和全局变量可以。
2. 验证了__forwarding在__block 结构体的指向(上边__forwarding的指向结论)

另一参数(方法): __main_block_desc_0_DATA

我们可以看到__main_block_desc_0中存储着两个参数:reserved
和Block_size;并且reserved赋值为0而Block_size则存储着__main_block_impl_0的占用空间大小。最终将__main_block_desc_0结构体的地址传入__main_block_func_0中赋值给Desc。

让我们在看看__testBlockA_block_impl_0 主方法里边的实现:

首先我们看一下__block_impl第一个变量就是__block_impl结构体。 来到__block_impl结构体内部

我们可以发现__block_impl结构体内部就有一个isa指针。因此可以证明block本质上就是一个oc对象。而在构造函数中将函数中传入的值分别存储在__main_block_impl_0结构体实例中,最终将结构体的地址赋值给block。

接着通过上面对__main_block_impl_0结构体构造函数三个参数的分析我们可以得出结论:

  1. __block_impl结构体中isa指针存储着&_NSConcreteStackBlock地址,可以暂时理解为其类对象地址,block就是_NSConcreteStackBlock类型的。
  2. block代码块中的代码被封装成__main_block_func_0函数,FuncPtr则存储着__main_block_func_0函数的地址。
  3. Desc指向__main_block_desc_0结构体对象,其中存储__main_block_impl_0结构体所占用的内存。

那么block是怎么执行的?

通过上述代码可以发现调用block是通过block找到FunPtr直接调用,通过上面分析我们知道block指向的是__main_block_impl_0类型结构体,但是我们发现__main_block_impl_0结构体中并不直接就可以找到FunPtr,而FunPtr是存储在__block_impl中的,为什么block可以直接调用__block_impl中的FunPtr呢?
重新查看上述源代码可以发现,(__block_impl *)block将block强制转化为__block_impl类型的,因为__block_impl是__main_block_impl_0结构体的第一个成员,相当于将__block_impl结构体的成员直接拿出来放在__main_block_impl_0中,那么也就说明__block_impl的内存地址就是__main_block_impl_0结构体的内存地址开头。所以可以转化成功。并找到FunPtr成员。
上面我们知道,FunPtr中存储着通过代码块封装的函数地址,那么调用此函数,也就是会执行代码块中的代码。并且回头查看__main_block_func_0函数,可以发现第一个参数就是__main_block_impl_0类型的指针。也就是说将block传入__main_block_func_0函数中,便于重中取出block捕获的值。

此时已经基本对block的底层结构有了基本的认识,上述代码可以通过一张图展示其中各个结构体之间的关系。

block底层的数据结构也可以通过一张图来展示

参考文章:https://www.jianshu.com/p/92f15fc9301a

相关文章

  • Block探索

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 程序占用内存分类 栈区...

  • Block底层分析

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 1. 研究工具:cla...

  • block分析(下)

    block通过clang分析 带着下面的疑问,我们去探索block原理 探索block底层源码 block在底层是...

  • block(二)-- 底层分析

    block(一):https://www.jianshu.com/p/b83574a8ef80连接上文拿到bloc...

  • Block底层hook

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 前言 如何反编译出微信...

  • Block经典问题循环引用&解决

    Block内存关系Block经典问题循环引用&解决Block底层分析Block底层HooK 1.循环引用怎么产生的...

  • block 底层原理分析(二)

    通过clang分析block 类似这样一段代码,我们通过 clang 之后生成 c++ 代码如下: 通过简化之后我...

  • OC底层面试知识点之 —— Block底层原理!

    本文将介绍block的类型,循环引用的解决方法以及block底层分析 Block简介 Block定义:带有自动变量...

  • Block 深入浅出

    标签:block block的类型 循环引用的解决方法 block底层的分析 本章节主要介绍 1.block的类型...

  • Block实现原理

    主要介绍block的类型和底层分析 block类型 block主要由三种类型 NSGlobalBlock:全局bl...

网友评论

      本文标题:block(二)-- 底层分析

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