iOS Block本质探究

1、编写测试代码 并将其转换成c++代码 查看具体实现

  • 进入main.m所在目录 执行  xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc main.m
  • 或者  xcrun  -sdk  iphoneos  clang  -arch  arm64  -rewrite-objc  OC源文件  -o   输出的CPP文件(main.cpp)


#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        int age = 20 ;
        void (^testBlock)(int,int) = ^(int a, int b){
            NSLog(@"Hello, World -=-%d",age);
        };
        testBlock(1,2);
        
        /* 等价于上面代码
         
         int age = 20 ;
         void (*testBlock)(int,int) = ((void (*)(int, int))&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, age));
         ((void (*)(__block_impl *, int, int))((__block_impl *)testBlock)->FuncPtr)((__block_impl *)testBlock, 1, 2);
         
         */
        /*
         内部
         struct __block_impl {
         void *isa;
         int Flags;
         int Reserved;
         void *FuncPtr;
         };
         
         static struct __main_block_desc_0 {
           size_t reserved;
           size_t Block_size;
         } __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
         
         
         
         //blcok定义
         struct __main_block_impl_0 {
         struct __block_impl impl;
         struct __main_block_desc_0* Desc;
         int age;
         __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags=0) : age(_age) {
         impl.isa = &_NSConcreteStackBlock;
         impl.Flags = flags;
         impl.FuncPtr = fp;
         Desc = desc;
         }
         };
         
         */
        
        /*
         
         struct __main_block_impl_0 {
         struct __block_impl {
         void *isa;
         int Flags;
         int Reserved;
         void *FuncPtr;
         };
         
         struct __main_block_desc_0* Desc;
         int age;
         __main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _age, int flags=0) : age(_age) {
         impl.isa = &_NSConcreteStackBlock;
         impl.Flags = flags;
         impl.FuncPtr = fp;
         Desc = desc;
         }
         };
         
         */
    }
    return 0;
}

 

 

  •  block本质上也是一个OC对象,它内部也有个isa指针
  •  block是封装了函数调用以及函数调用环境的OC对象  
    FuncPtr 指针指向 函数调用地址
    age是外部传入的
  • __main_block_desc_0 里包含了block的大小
posted @ 2020-02-16 21:25  ZhangShengjie  阅读(121)  评论(0编辑  收藏  举报