.
weakSelf是用来解决循环引用
strongSelf则是保证任何情况下self在超出作用域以后仍旧能够使用。
示例
定义个自定义的类HRViewController。通过touchesBegan:跳转到这个Controller,在HRViewController里面的``touchesBegan:来实现退出HRViewController控制器。通过进入和退出HRViewController`来查看效果。
前置条件
1 2 3 4 5 6 7 8
| @interface HRViewController () @property (copy, nonatomic) void(^test)(); @property (nonatomic, copy) NSString *locationInfo; @end
-(void)dealloc { NSLog(@"HRViewController销毁"); }
|
WeakSelf
1 2 3 4 5 6 7 8 9 10
| - (void)viewDidLoad { [super viewDidLoad]; self.locationInfo = @"北京"; self.test = ^{ NSLog(@"地址:%@", self.locationInfo); }; self.test(); self.view.backgroundColor = UIColor.redColor; }
|
上面的代码会导致死循环,HRViewController销毁不会被打印。Controller拥有这个Block,这个Bock强引用Controller,所以不会被销毁。如下面代码,block中改为弱引用,问题解决,HRViewController销毁打印。
1 2 3 4 5 6 7 8 9 10 11
| - (void)viewDidLoad { [super viewDidLoad]; self.locationInfo = @"北京"; __weak HRViewController *weakSelf = self; self.test = ^{ NSLog(@"地址:%@", weakSelf.locationInfo); }; self.test(); self.view.backgroundColor = UIColor.redColor; }
|
StrongSelf
1 2 3 4 5 6 7 8 9 10
| __weak HRViewController *weakSelf = self; self.test = ^{ NSLog(@"地址:%@", weakSelf.locationInfo); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"执行延时"); strongSelf.locationInfo = @"湖南"; NSLog(@"地址:%@", weakSelf.locationInfo); }); }; self.test();
|
进入Controller以后,在5秒内退出这个Controller。执行到延时block里面的代码的时候,Controller已经销毁了,locationInfo也随之销毁了,所以湖南不能被赋值,里面的打印地址为null。
1 2 3 4
| 地址:北京 HRViewController销毁 执行延时 地址:(null)
|
这时候我们就要用到strongSelf来延迟Controller的销毁。
1 2 3 4 5 6 7 8 9 10 11
| __weak HRViewController *weakSelf = self; self.test = ^{ NSLog(@"地址:%@", weakSelf.locationInfo); __strong HRViewController *strongSelf = weakSelf; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"执行延时"); strongSelf.locationInfo = @"湖南"; NSLog(@"地址:%@", strongSelf.locationInfo); }); }; self.test();
|
从打印可以看出Controller最终在赋值完以后才销毁,所以达到了延迟Controller的销毁的目的。
1 2 3 4
| 地址:北京 执行延时 地址:湖南 HRViewController销毁
|
不能直接在延迟block里面使用self,这样又是会死循环。
相关链接
https://stackoverflow.com/questions/11013587/differences-between-strong-and-weak-in-
https://blog.csdn.net/u013046795/article/details/50789442