一: block的基础用法
block声明: int(^blockDemon)(inta,intb) ,其中int : 为返回值,
blockDemon: 为block变量名称,
(int a, int b): 为block接收参数
block实现:^(int a, int b){returna + b;
}
截获自动变量值:
block会自动保存变量的瞬间值,尽管对变量进行重新赋值操作,block 内部依旧会保存变量原先值
__block说明符号:
自动变量截获的值为block声明时刻的瞬间值,
保存后就不能改写该值(但可读),如需对自动变量进行重新赋值,需要在变量声明前附加__block说明符,这时该变量称为__block变量。
自动变量值为一个对象的特殊情况(没有使用__block),当自动变量为一个类的对象,且没有使用__block修饰时,虽然不可以在Block内对该变量进行重新赋值,但可以修改该对象的属性。
二: block的循环引用
最简单的例子:
[self.teacher requestData:^(NSData *data) {
self.name = @"case";
}];
self强引用了teacher,而teacher又强引用了一个block,而block在回调时又强引用了self,形成一个保留环,即self-->teacher-->block-->self,最终导致内存泄露。
一般的解决办法:
__weak typeof(self) weakSelf = self;
[self.teacher requestData:^(NSData *data) {
typeof(weakSelf) strongSelf = weakSelf;
strongSelf.name = @"case";
}];
通过__weak修饰符,这样就打破了保留环,即self-->teacher-->block-->weakSelf。
三: block的结构与实质
使用block的时候,编译器对block做了什么:
经过分析工具clang后: