![](https://img.haomeiwen.com/i2946773/0a197181104777dc.png)
对于block中的全局变量和静态变量,block中改变量的地址不发生变化;对于一般变量,block中会对此变量进行拷贝,其修改不会影响外部变量;对于block变量,block会将其转移到堆中(外部变量地址也会发上变化),block中直接可以修改此变量。
Block的用法
1、作为一个本地变量(local variable)
returnType (^blockName)(parameterTypes) = ^returnType(parameters) {
//blablabla
};
2、作为@property
@property (nonatomic, copy) returnType (^blockName)(parameterTypes);
3、作为方法的参数(method parameter)
- (void)someMethodThatTakesABlock:(returnType (^)(parameterTypes))blockName;
4、作为方法参数的时候被调用
[someObject someMethodThatTakesABlock: ^returnType (parameters) {...}];
5、使用typedef来定义block
typedef returnType (^TypeName)(parameterTypes);
TypeName blockName = ^returnType(parameters) {...};
为什么使用weakSelf
通过 clang -rewrite-objc 源代码文件名 将代码转为c++代码(实质是c代码),可以看到block是一个结构体,它会将全局变量保存为一个属性(是__strong的),而self强引用了block这会造成循环引用。所以需要使用__weak修饰的weakSelf。
为什么在block里面需要使用strongSelf
是为了保证block执行完毕之前self不会被释放,执行完毕的时候再释放。这时候会发现为什么在block外边使用了__weak修饰self,里面使用__strong修饰weakSelf的时候不会发生循环引用
不会引起循环引用的原因
因为block截获self之后self属于block结构体中的一个由__strong修饰的属性会强引用self, 所以需要使用__weak修饰的weakSelf防止循环引用。
block使用的__strong修饰的weakSelf是为了在block(可以理解为函数)生命周期中self不会提前释放。strongSelf实质是一个自动变量,当block执行完毕就会释放自动变量strongSelf,不会对self进行一直进行强引用。
总结
外部使用了weakSelf,里面使用strongSelf却不会造成循环,究其原因就是因为weakSelf是block截获的属性,而strongSelf是一个自动变量会在函数执行完释放。
Demo 中有一些关于Block的使用说明。
网友评论