在main函数中声明一个block对象,在内部访问一个局部变量age:

    1. int age = 10;
    2. void (^block)(void) = ^{
    3. NSLog(@"age = %d",age);
    4. };
    5. block();

    将main.m转换成.cpp文件(参考:OC代码转换 ),转换后main函数内部代码:

    1. int age = 10;
    2. // 创建block
    3. void (*block)(void) = &__main_block_impl_0(
    4. __main_block_func_0,
    5. &__main_block_desc_0_DATA,
    6. age
    7. );
    8. // 执行block方法
    9. block->FuncPtr(block);

    其中main_block_func_0封装了block内部执行的函数,最后会赋值给FuncPtr,main_block_desc_0_DATA保存了block描述信息,age会保存到block结构体中。
    block结构体代码:

    1. // block结构体
    2. struct __main_block_impl_0 {
    3. struct __block_impl impl;
    4. struct __main_block_desc_0* Desc;
    5. int age;
    6. };
    7. struct __block_impl {
    8. void *isa;
    9. int Flags;
    10. int Reserved;
    11. void *FuncPtr;
    12. };
    13. static struct __main_block_desc_0 {
    14. size_t reserved;
    15. size_t Block_size;
    16. }

    block数据结构如下图所示:
    image.png

    由于block底层也是结构体,且也存在isa指针,所以可推断出block本质是OC对象。
    打印block的class、block的父类以及父类的父类

    1. NSLog(@"block.class = %@",[block class]);
    2. NSLog(@"block.class.superclass = %@",[[block class] superclass]);
    3. NSLog(@"block.class.superclass.superclass = %@",[[[block class] superclass] superclass]);

    打印结果:

    1. ~:block.class = __NSMallocBlock__
    2. ~:block.class.superclass = NSBlock
    3. ~:block.class.superclass.superclass = NSObject

    这样进一步印证了block就是一个继承于NSBlock的OC对象。