在ios常见的循环引用中曾经提到过block:

看看上面最基本的block循环应用,self包含block,block包含了self中的变量val,所以形成了循环应用,编译器给出了循环引用的警告,当然不是所有的block循环引用编译器都能给出警告,所以不要只依赖编译器的警告来判断循环引用,如:

解决的办法当然是使用__weak来修饰self
1__weak typeof(self) weakSelf = self; 2blkk = ^{ 3 [weakSelf showLog]; 4}; 5blkk();
-------------------------------凌乱分割线-------------------------------
正常在栈上的block引用self是不会引起循环应用的,所以可以不使用weak来修饰self
1void (^blkk)(void) = ^{ 2 [self showLog]; 3}; 4blkk();
但是因为block的使用附有__strong的原因,虽然不会有循环引用,但是也会起到延长self对象的生命周期的效果,直到栈上的block释放了,才会释放self。
因此释放self可能会让程序出现问题,假如self监听了某些通知而修改公共资源什么的,所以这种情况下最好也使用weakself。
当然你也可能不希望self提前释放,因为你的block回调后需要进行完整操作,假如self释放了,你无法在block回调后来处理一些其他的事情,这时候你可以选择不使用weakself,也可以使用weakself+strongself。先看看weakself+strongself的写法:
1__weak __typeof__(self) weakSelf = self; 2 3createdTask = [self.sessionManager 4 dataTaskWithRequest:request 5 completionHandler:^(NSURLResponse * _Nonnull response, id _Nullable responseObject, NSError * _Nullable error) { 6 dispatch_async(self.responseQueue, ^{ 7 __strong __typeof__(weakSelf) strongSelf = weakSelf; 8.....
上面是AFNetworking的源码,在block前用了weakself,在block里用了strongself,这样做和直接不使用weakself有什么区别呢。
block回调前结束self
block回调后结束self
不使用weakself
self 不释放
self不释放
weakself+strongself
self已释放
self不释放
使用weakself
self已释放
self已释放
所以根据情况的不同,大家可以选择使用哪种方式。当然最无脑的推荐还是使用weakself