首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Blocks笔记(1)

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
返回列表