美文网首页
底层7:block本质

底层7:block本质

作者: 张无奈 | 来源:发表于2020-08-30 00:28 被阅读0次

    面试题:block的原理是怎样的?本质是什么?

    block是封装了函数调用及其函数调用环境的OC对象,本质就是oc对象,内部存在isa指针。



    block本质:也是一个OC对象,它内部也有isa指针。

    block是封装了函数调用以及函数调用环境的OC对象。

    通过命令 xcrun -sdk iphoneos -arch arm64 -rewrite-objc main.m 得出对应main.m文件的c++源码:

    int age = 20;

    void(^block)(void) = ^{

    NSLog("Hello, word");

    } block();

    底层实现大致如下:底层是一个block_impl_0的结构体,里面包含一个impl的结构体,该结构体中存在isa指针,FuncPtr是要执行的内部方法地址;desc结构体里面包含默认值为0的reserverd,和表示结构体大小的block_size;age是捕获进来的变量。

    block的变量捕获

    为了保证block内部能够正常访问外部的变量,block有个变量捕获机制

    auto:自动变量,离开作用域就会自动销毁

    static:

    下面方法中的self有没有被捕获,即是不是局部变量?

    是局部变量,因为方法等价于-(void)test:(id)self cmd:(SEL)cmd; self是作为一个参数传进来的,是局部变量。

    下面的_name会被捕获吗?

    它是先捕获self,再去调用self里面的name,因为_name=self.name

    block类型:

    block有3种类型,可以通过调用class方法或者isa指针查看具体类型,最终都是继承自NSBlock类型(因为本质是OC对象,所以可以调用class方法和isa指针,还有就是isa指针也是因为它继承于nsobject)。

    类型一切以运行时为准;clang 生成c++;llvm x.0 可能生成一些中间文件

    应用程序的内存分配从高到低地址是:

    栈区-->堆区-->数据区域(.data区)-->程序区域(.text区)

    栈区存放_NSConcreteStackBlock;

    堆区存放_NSConcreteMallocBlock

    数据区域存放_NSConcreteGlobalBlock

    特别注意:在打印的时候有可能出现结果跟预想不一致的情况,这需要我们手动将ARC改成MRC,因为ARC自动管理可能给我们做了很多工作,导致跟预期不一致。

    这个栈block打印出来是一串垃圾数据,原因就是因为栈block在栈区,会被销毁掉,所以打印它的数据是垃圾数据。解决这个问题需要将栈block通过copy转为堆block,如下

    全局block调用copy后还是全局block:

    结论:每一种类型的block调用copy后的结果如下:

    相关文章

      网友评论

          本文标题:底层7:block本质

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