場景:當你在某個界面請求網絡數據的時候,用戶不肯意等待點擊了返回按鈕,此時在Block當中用以下的方式使用weakSelf的話,有可能會奔潰(由於在併發編程的狀況下,雖然在if判斷的時候weakself不爲空,可是不保證if語句裏面的weakself不爲空),因此爲了安全起見要加上strongSelf(參考)。ios
if (weakSelf != nil) { // last remaining strong reference released by another thread. // weakSelf is now set to nil. [myArray addObject:weakSelf]; }
那爲何加上strongSelf就能夠保證self不爲空了?編程
由於若是self有效,那麼strongself就是利用了循環引用的特性保證了在block執行的時候self對象不會被析構,strongSelf是局部變量執行完成後就會釋放安全
接下來用個Demo驗證下,在FirstVC的ViewDidLoad裏面添加如下代碼網絡
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.5* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.navigationController pushViewController:[SecondVC new] animated:NO]; }); //0.025 - 0.03 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (0.55 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self.navigationController popViewControllerAnimated:NO]; });
而後在 SecondVC的 裏面添加如下代碼併發
typedef void(^TTestBlock)(int result); @interface SecondVC () @property (strong, nonatomic) TTestBlock aBlock ; @end @implementation SecondVC - (void)viewDidLoad { [super viewDidLoad]; [self testForBlock]; } - (void)testForBlock{ __weak typeof(self) wSelf = self; self.aBlock = ^(int result) { NSLog(@"testForBlock:%@",wSelf); dispatch_async(dispatch_get_global_queue(0, 0), ^{ //沒有下面這一行的話,testForBlock2 中的self爲空 __strong typeof(wSelf) strongSelf = wSelf; NSLog(@"testForBlock1:%@",wSelf); [NSThread sleepForTimeInterval:1]; //__strong typeof(wSelf) strongSelf = wSelf; //放在這兒的話也wSelf會爲空 NSLog(@"testForBlock2:%@",wSelf); }); } ; self.aBlock(0); } @end
注意:async