OC中的block也是一种对象,它的本质是结构体。
我们在调用block的时候应该判空,如果block为空,我们还去调用就会直接crash掉。
这里block为空不是nil,而是null。
0.null.jpg
调用block走的不是OC中调用方法的消息机制,(swift中函数派发机制)block的地址在编译期已经确定了调用的地址。
当block为空的时候,CPU会去访问地址address=0x10,这样就会报EXC_BAD_ACCESS错误。
别人更深入的解释(https://blog.csdn.net/blog_jihq/article/details/79189919)
address=0x10问题的原因在是block的结构体寻址问题
看block结构
//__block_imp: 这个是编译器给我们生成的结构体,每一个block都会用到这个结构体
struct __block_impl {
void *isa; //类型
int Flags; //标识字段
int Reserved; //保留字段
void *FuncPtr; //函数指针,这个会指向编译器给我们生成的下面的静态函数__main_block_func_0
};
0x10是十六进制,也就是struct基地址后的第16个字节,其中void *类型占8个字节,int类型占4个字节,所以0x10的地址就是FuncPtr的地址,而address=0x10的问题也正是对值为nil的block强行调用导致的
网友评论