1.block的循环引用
block在copy时都会对block内部用到的对象进行强引用(ARC)或者retainCount增1(非ARC)。在ARC与非ARC环境下对block使用不当都会引起循环引用问题,一般表现为,某个类将block作为自己的属性变量,然后该类在block的方法体里面又使用了该类本身,简单说就是self.someBlock = ^(Type var){[self dosomething];或者self.otherVar = XXX;或者_otherVar = ...};block的这种循环引用会被编译器捕捉到并及时提醒,代码如下:
self.block = ^(NSString *name){
NSLog(@"arr:%@", [self dosomething]);
};
此时造成了引用环,结构如下:
去除引用环用__weak,代码如下:
__weak typeof(self) weakSelf = self;
self.block = ^(NSString *name){
NSLog(@"arr:%@", [weakSelf dosomething]);
};
2.防止self对象被释放,而用__strong修饰
我们常常会使用weak 的修饰符来修饰一个变量,防止其在block中被循环引用,但是有些特殊情况下,我们在block中又使用strong 来修饰这个在block外刚刚用__weak修饰的变量。在block代码块内,用__strong修饰weakSelf可以使self对象的引用+1,从而保证在self被置空的时候,retaincount不为零,对象依然存在;而strongself又是在代码块中定义的局部变量,这样就可以在block执行完之后,释放strongself,此时retaincount为零释放self,如下图:
__strong 是为了在多线程中防止执行block时,self被其他线程释放,而导致block代码块内weakself=nil。