01- void (*block)() 变量 函数指针
void (*block)() = &__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, a));
a = 20;
//类 c++里面结构体可以 添加函数
//构造函数 init 开头的所有函数
//初始化
struct __main_block_impl_0 {
struct __block_impl impl;
struct __main_block_desc_0* Desc;
int a;
__main_block_impl_0(void *fp, struct __main_block_desc_0 *desc, int _a, int flags=0) : a(_a) {
impl.isa = &_NSConcreteStackBlock;
impl.Flags = flags;
impl.FuncPtr = fp;
Desc = desc;
a= _a;
}
};
fp 万能指针 空指针
desc 描述 struct __main_block_desc_0 结构体指针
_a
struct __main_block_desc_0* 结构体类型的指针
static struct __main_block_desc_0 {
size_t reserved;
size_t Block_size; //大小 就是之前的block 的大小
} __main_block_desc_0_DATA = { 0, sizeof(struct __main_block_impl_0)};
: a(_a) 将来 a = _a
a = _a
FuncPtr 保存fp
1.用结构体的构造函数 初始化一个结构体(函数指针) 变量
2.传递了三个参数过去
FuncPtr 保存fp 保存了一个需要执行的函数 这里就是有着打印代码的函数
desc __main_block_desc_0_DATA 保存了 __main_block_impl_0的结构体的大小
a = _a 保存了一个数值 这里是 10;
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);
FuncPtr()执行
1.对__block 修饰的变量进行 封装
__Block_byref_a_0 结构体
__Block_byref_a_0 a = {(void*)0,(__Block_byref_a_0 *)&a, 0, sizeof(__Block_byref_a_0), 10};
struct __Block_byref_a_0 {
void *__isa; //类型
__Block_byref_a_0 *__forwarding; //自己类型的指针 存储了自己的地址 有了地址就有了最高操作权限 (改值)
int __flags; //标记
int __size; //大小
int a; //变量 将来可能保存之前的20
};
void (*block)() = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA, (__Block_byref_a_0 *)&a, 570425344));
保存 了 __Block_byref_a_0 a 的地址 该变量是 经过 __block 关键字修饰过的 变量
(a.__forwarding->a) = 20;
printf("%d\n",(a->__forwarding->a));
传址
block 实质:
结构体的指针 函数指针
传值
1.创建初始化一个结构体
__main_block_impl_0
2.传递三个参数
(fp - > FuncPtr (打印函数的指针))
desc 描述类的结构体 (包含大小)
a (赋值给属性 _a 不是指针)
3.调用FuncPtr保存的函数 打印
传址
1.对 __blcok 修饰的变量进行 封装 -> 封装成一个 __Block_byref_a_0的 a 结构体
四个参数
void *__isa; //类型
__Block_byref_a_0 *__forwarding; //自己类型的指针 存储了自己的地址 有了地址就有了最高操作权限 (改值)
int __flags; //标记
int __size; //大小
int a; //变量 将来可能保存之前的20
2.创建一个 __main_block_impl_0结构体传递四个参数
第三个 参数 :类型 __Block_byref_a_0 * 指针 实参 : a
保存在 _a -> : __Block_byref_a_0 *a; // by ref a的地址
3.(a.__forwarding->a) = 20;
通过地址 找到属性 值的修改
4.FuncPtr 的打印