什么是block
block:是封装了函数调用以及函数环境的对象
void(^Block)(void) = ^() {
int a = 10;
};
Block();
NSLog(@"%@",[Block class]);
NSLog(@"%@",[[Block class] superclass]);
NSLog(@"%@",[[[Block class] superclass] superclass]);
NSLog(@"%@",[[[[Block class] superclass] superclass] superclass]);
/// 打印结果 __NSGlobalBlock__ __NSGlobalBlock NSBlock NSObject
证明了block 是对象
###block的三种类型
__NSGlobalBlock__ __NSMallocBlock__ __NSStackBlock__
他们之间的关系
![WechatIMG74.png](https://upload-images.jianshu.io/upload_images/9717104-94f6a32f0cbc2bba.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
struct __main_block_impl_0 {
struct __block_impl impl;
// void *isa;
// int Flags;
// int Reserved;
// void *FuncPtr;
struct __main_block_desc_0* Desc;
__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的定义和调用
// 定义
void(*Block)(void) = ((void (*)())&__main_block_impl_0((void *)__main_block_func_0, &__main_block_desc_0_DATA));
// 调用
((void (*)(__block_impl *))((__block_impl *)Block)->FuncPtr)((__block_impl *)Block);
// 去掉中间的类型强制转换
Block->FuncPtr(Block);
变量捕获
在MRC环境下什么情况block 会执行copy操作
1.返回值是block
2.有强指针指向
循环引用的问题
你中有我我中有你
解决方法:
打破循环引用链
__weak typyof(self) weakself = self;
__unsafe__unretained id weakself = self;
__block id weakself = self;