關於iOS Block當中為什么要用weakSelf和strongSelf的思考


  場景:當你在某個界面請求網絡數據的時候,用戶不願意等待點擊了返回按鈕,此時在Block當中用如下的方式使用weakSelf的話,有可能會奔潰(因為在並發編程的情況下,雖然在if判斷的時候weakself不為空,但是不保證if語句里面的weakself不為空),所以為了安全起見要加上strongSelf(參考)。

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

 

 

注意:

  • 關於Masonry里面的Block:函數參數里面的Block是局部的block(棧上),block內部引用self不會造成循環引用;是否會循環引用只看函數內部是否copy了這個block(比如把它付給全局的Block)(參考
  • 關於IBOutlet的weak:因為xib里面的根視圖已經強引用了拖拽上去的UI控件了,所以拖拽到VC里面用weak就行(參考
  • 關於weak的實現原理:Runtime維護了一個weak(hash)表,用於存儲指向某個對象的所有weak指針;當對象的強引用計數為0的時候,會找到該對象的所有weak指針,將它置為nil。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM