既然在修饰block时,使用了strong,那么另一个问题就需要注意了,也就是循环引用。
当使用了strong修饰后,self会强引用block,而如果在block中又需要访问self的一些属性或者方法,从而调用了self,这时self和block就进入循环引用,容易内存溢出。
解决的办法时在block中的需要用到self时,事先将self用__weak修饰,这样互相引用的一方就不再是强引用了。
__weak ViewController *weakSelf = self;self.block = ^{
weakSelf.str = @"123";
};
但是这样还不够,在多线程下,单单使用weakSelf,可能前一刻weakSelf还在,后面需要用时却被释放掉了,毕竟弱引用是不稳定的,这时候就需要又使用一个修饰符__strong来在block中修饰,是不是操碎了心。
__weak __typeof(self) *weakSelf = self;
self.block = ^{
__strong __typeof(self) strongSelf = weakSelf;
if (strongSelf) {
strongSelf.str = @"123";
}
// 如果不用了,应置为空
strongSelf.block = nil;
};
__block本身并不能避免循环引用,避免循环引用需要在block内部把__block修饰的obj置为nil,且需要在外部调用一下
__block MyObject *blockObj = obj;
void(^testBlock)() = ^(){ TLog(@"blockObj - block",blockObj);
blockObj = nil;};
testBlock();
__weak可以避免循环引用,但是其会导致外部对象释放了之后,block 内部也访问不到这个对象的问题,我们可以通过在 block 内部声明一个 __strong
的变量来指向 weakObj,使外部对象既能在 block 内部保持住,又能避免循环引用的问题
网友评论