Board logo

标题: Blocks笔记(1) [打印本页]

作者: look_w    时间: 2019-2-19 15:42     标题: Blocks笔记(1)

block是什么? block本质其实是能够截获自动变量的匿名函数,是一个oc对象(结构体),结构体里面的isa指针指向自己的类,但是它和对象又有一定的区别. 对象一般分配在堆上,而block默认分配在栈上(其他情况下面会说明),Block是C的扩展,指向结构体__main_block_impl_0的指针,创建__main_block_impl_0结构体时会根据变量环境初始化结构体成员变量,由此来分配内存区域,截获变量,管理内存,以及一些copy操作.

block的结构

通过clang工具翻译oc代码可以看到block的结构体信息,具体含义见注释

    #import "test.h"
     
    @implementation test
    //oc代码
    - (instancetype)init {
        if (self == [super init]) {
            void(^testBlock)() = ^{
                NSLog(@"hello world!");
            };
            testBlock();
        }
        return self;
    }
     
    @end
    clang -rewrite-objc test.m
    //clang翻译之后的截取代码
    // @implementation test
     
    //block指向__test__init_block_impl_0此结构体,block的入口
    struct __test__init_block_impl_0 {
      struct __block_impl impl; //见下面
      struct __test__init_block_desc_0* Desc; //描述block信息的结构体
     //结构体的构造函数,含有初始化参数
       __test__init_block_impl_0(void *fp, struct   __test__init_block_desc_0 *desc, int flags=0) {
        impl.isa = &_NSConcreteStackBlock; //block 创建在栈区,因此父类为_NSConcreteStackBlock
        impl.Flags = flags;
        impl.FuncPtr = fp;
        Desc = desc;
       }
    };
     
    //block实现的结构体
    struct __block_impl {
      void *isa; //指向所属的类
      int Flags; //按位承载 block 的附加信息;
      int Reserved; //保留变量
      void *FuncPtr; //函数指针,指向block执行的函数
    };
     
    //block要执行的函数代码
    static void __test__init_block_func_0(struct __test__init_block_impl_0 *__cself) {
      NSLog((NSString *)&__NSConstantStringImpl__var_folders_gd_3sky2l_d5jv0t9ww_t8_w3680000gp_T_test_87f55d_mi_0);
    }
     
    //描述block信息结构体
    static struct __test__init_block_desc_0 {
      size_t reserved;
      size_t Block_size;
    }
     
    //结构体变量
    __test__init_block_desc_0_DATA = { 0, sizeof(struct __test__init_block_impl_0)};
     
    // @end




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0