这是我参与8月更文应战的第30天,活动详情检查: 8月更文应战

汇编剖析block流程

在上一篇文章中咱们剖析了block的底层结构,接下里咱们剖析一下block的实施流程;

咱们新建一个iOS工程,然后编写如下代码:

iOS底层剖析-block(三)

block的当地打开源代码网站github上断点,然后工作项目,翻开汇编界面:

iOS底层剖析-block(三)

在汇编代码中,咱们定位到了objc_retainBlock这样一个符号;咱们增加符源码之家号断点objc_retainBloc变量泵k,持续实施代码:

iOS底层剖析-block(三)

发现接下来ioslauncher,将会调用_Block_copy,持续增加符号断点_Block_copy,向下实施代码:

iOS底层剖析-block(三)

发现_Block_copy开源中国来自于libsystem_b源码locks.dyl变量英文ib,同样的调用咱们从objc的源码中也能够剖析得到:

iOS底层剖析-block(三)

定位到_Block源码资本_copy之后,咱们无法持续向下剖析,由于libsystem_blocks没有开源源码共享网;可是咱们变量名的命名规矩能够从libclosure的源码中找到_Block_copy的完结:

iOS底层剖析-block(三)

_Block_copy中,界说了一个结构体struct Block_layout *aBlock;,其结构如下:

iOS底层剖析-block(三)

  • 结构体中有个isa的成员变量,(指向栈block或许堆block)
  • flags标识码,里边能够存储一些数据信息;
  • invoke是调变量用函数;
  • descriptor相关描绘信息(比如是否有有析构函数等等信息)

此刻,咱们打印一下寄存器中的数据:

iOS底层剖析-block(三)

  • x0是音讯接收者,它是一个__NSGlobalBlock__,由于现在咱们的block没有捕获任何的外部变量;

接下来咱们将block代码修改如下:

iOS底层剖析-block(三)

持续实施代码到_Block_copy的符指针数学号断点,咱们打印一下x0寄存器的数据:

iOS底层剖析-block(三)

  • 由于此刻block捕获了外部变量,所以他此刻是一个__NSStack变量与函数Block__,是个栈block;可是依照咱们之前剖析的成果,block捕获了外部变ios体系量,而且是强引证,它应该是一个堆block才对啊,这儿为什么变成了栈block了,前后矛盾???

可是需求留意的是,此刻咱们的程序在断点过程中,_Block_copy还没有实施结束!

那么咱们在_Blo指针ck_copy最终return的当地打上断点,向下实施,我么你看一下returnx0寄存器中的情况:

iOS底层剖析-block(三)

  • _Block_copy方法开始实施时,与实施结束之后return时,x0寄存器地址发生了改动,而且从__NSStackBlock__变成了__NSMallocBlock__;
  • _开源阅览app下载安装Block_copy方法将一个栈block变成了堆block

咱们现在从汇编视点剖析出了block的改动,接开源代码网站github下来咱们从源码中剖析验证一下;

源码剖析block流程

_Block_copy的源码完结如下:

iOS底层剖析-block(三)

解析:

  • (aBlock->fla变量提高gs & BLOCK_NEEDS_FREE)假定block被标识为开释的,那变量么直接retur源码之家n;
  • (aBlock->flags & BLOCK_IS_GLOBAL)假定block被标识为大局的,那么直接return;
  • size_t size = Block_size(aBlock);ios下载block的巨细;
  • struct Block_layout *result = (struct Block_layout *)malloc(size)依照巨细开荒内存空间;
  • memmove(result, aBlock, size)将aBlock拷贝到result中;
  • result->isa = _NS源码交易平台ConcreteMallocBlockbloc指针万用表的使用方法视频教程k从头标记为堆block;

编译期生成的只能是栈block,由于在编译期没有alloc等操作,没有内存的开荒,所以只能标记为栈block,然后在工作时从头将栈block标记为堆block

咱们细心检查控制台打印信息的时分发现,除了打印出以上内容之后,还打印出了signatur变量e: "v8@?0"invokecopydispose这些信息;那么他们都是什么东西呢?

  • signature是咱们当ios是什么意思block的签名;

咱们能够经过下面的方式来检查这个签名信息:

iOS底层剖析-block(三)

  • 解析

    • number of arguments = 1:传递了1个参数;
    • is special struct return? NO:没有返回值;
    • argument 0::参数从0号方位开始;
    • flags {isObject, isBlock}:是一个block,也是一个政策,也便是一个block类型的政策;
  • invoke是函数的调用者的指针;

那么copydisposeblock有什么影响呢?咱们下次指针和引证的区别持续说明……