block原理学习(1.block的底层数据结构)

blcok可以理解为一个代码块,但实质上是一个对象,封装了函数调用以及函数调用环境的oc对象
定义一个简单的block:


void (^block)(void) =  ^(void){
	NSLog(@"this is a block");
};
block();

用clang通过命令行以
xcrun -sdk iphoneos clang -arch arm64 -rewrite-objc
把oc语言转换成c++底层代码并把强制转换如下:

void (*block)(void) = &__main_block_impl_0(__main_block_func_0, 
        						  			  &__main_block_desc_0_DATA));
block->FuncPtr(block);
  1. __main_block_impl_0是一个结构体包括内容如下:
struct __main_block_impl_0 {
    struct __block_impl impl;
    struct __main_block_desc_0* Desc;
    // 构造函数(类似于OC的init方法),并把参数传进去,返回结构体对象
  	__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int flags=0) {
    impl.isa = &_NSConcreteStackBlock;
    impl.Flags = flags;
    impl.FuncPtr = fp;
    Desc = desc;
  }
};

第一个 __block_impl 并不是一个指针也是一个结构体,其中isa是一个指针证明block是一个对象,其中FuncPtr是一个方法调用调用自己的方法

struct __block_impl {
    void *isa;
    int Flags;
    int Reserved;
    void *FuncPtr;
};

另外一个__main_block_desc_0是一个结构体指针,里面的两个参数之一的Block_size代表的是一个block的内存大小

struct __main_block_desc_0 {
    size_t reserved;
    size_t Block_size;
};

2.第一个参数__main_block_func_0封装了block执行逻辑的函数也就是{}内部执行的函数,也就是构造函数的void *fp,地址赋值给了impl的FuncPtr,所以FuncPtr也就是执行block函数的地址

static void __main_block_func_0(struct __main_block_impl_0 *__cself) {
            NSLog((NSString *)&__NSConstantStringImpl__var_folders_2r__m13fp2x2n9dvlr8d68yry500000gn_T_main_c60393_mi_0);
        }

3.第二个参数是定义了一个 __main_block_desc_0_DATA结构体变量,赋值给了reserved ,sizeof(struct __main_block_impl_0)计算了__main_block_impl_0的size,并赋值给了我Block_size

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)};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值