这两个宏相信大家一定都不陌生,也知道该如何使用。
本篇文章主要讲到下面几点问题,如果你都知道那么恭喜你,可以不用看这篇文章了。
1、为什么前面有个@号?
2、为什么一定要配对使用,为什么block里面不写strongify还是会造成循环引用?
3、最简单写法?
答案在此:
1、为什么前面有个@号?
答:纯粹为了装逼,这个@号实际上是一个@autoreleasePool{},宏命令中只写了autoreleasePool{},所以@符号需要外部传入;
2、为什么一定要配对使用,block里面不写strongify为什么还是会循环引用?
答:以 @weakify(self) 为例,首先,@weakify(self)最终实际上是生成了一个对self弱引用的变量 self_weak_;其次,@strongify(self)最终实际上是生成了一个对self_weak_强引用的变量 self,是的你没有看错,变量名称就叫self,这就是为什么我们block里面的self不用改名字也不会造成循环引用的原因,因为你写的self和外面的self已经不一样了(self:我们不一样..不一样...)!
明白了以上两点,那么这个问题就很好理解了,其实就是一个“创建weak-替换self”的过程,所以必须配对使用。
让我们来实践一下,如果只写@weakify(self),编译器会报黄色警告 unused variable 'self_weak_'。
@weakify(self)
// Warning: Unused variable 'self_weak_'
反之如果只写@strongify(self),编译器则会报红色错误 undefined identifier 'self_weak_'。
@strongify(self)
// Error: Used undefined identifer 'self_weak_'
其次,在@strongify(self)宏之前写的self,代码提示会告诉你self是当前类,而在@strongify(self)宏之后写的self,代码提示会告诉你这个self是个typeof(self),也验证了此self非彼self,self已经被替换掉 (self: 我们不一样..不一样...) !
@weakify(self)
void(^block)() = ^{
//self is a const objct indentifier associated to your current class.
strongify(self)
//self is a 'typeof (self)' variable.
}
所以block里面不写strongify的话self没有被替换掉,所以当然会导致循环引用咯!
3、最简单写法?
__weak typeof(self) wself = self;
void(^block)(void) = ^{
__strong typeof(wself) self = wself;
}