iOS開發-多層嵌套block中如何使用__weak和__strong

一、關於__weak
__weak只能在ARC模式下使用,也只能修飾對象(好比NSString等),不能修飾基本數據類型(好比int等)
__weak修飾的對象在block中不能夠被從新賦值。
__weak只在ARC下使用,能夠避免循環引用。
__weak修飾對象不會增長引用函數

    __weak __typeof(self) weakSelf = self;spa

    self.testBlock = ^{.net

        [weakSelf doSomeThing];指針

    });對象


弱引用不會影響對象的釋放,可是當對象被釋放時,全部指向它的弱引用都會自定被置爲 nil,這樣能夠防止野指針。blog

二、關於__block
__block無論是ARC仍是MRC模式下均可以使用,能夠修飾對象,還能夠修飾基本數據類型。
在MRC下使用__block是能夠避免循環引用的;
在ARC下使用 __block typeof(self)weakSelf = self;由於block是用過添加引用來訪問實例變量的,因此self會被retain一次,block也是一個強引用,會引發循環引用。生命週期

__block修飾對象會增長引用get

三、關於 __strongit

- (void)viewDidLoad {table

    [super viewDidLoad];

    

    MyOBJ *mm = [[MyOBJ alloc]init];

    mm.name = @"Lilei";

    __weak typeof(student) weakSelf = mm;

    

    mm.doBlock = ^{

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSLog(@"my name is = %@",weakSelf.name);

        });

    };

    

    mm.doBlock();

}

//輸出:my name is = (null)


在dispatch_after這個函數裏面。在doBlock()的block結束以後,mm被自動釋放了。
又因爲dispatch_after裏面捕獲的__weak的mm,在原對象釋放以後,__weak對象就會變成nil,防止野指針。

那麼咱們怎麼才能在weakSelf以後,block裏面還能繼續使用weakSelf以後的對象呢?

究其根本緣由就是weakSelf以後,沒法控制何時會被釋放,爲了保證在block內不會被釋放,須要添加__strong。

在block裏面使用的__strong修飾的weakSelf是爲了在函數生命週期中防止self提早釋放。strongSelf是一個自動變量當block執行完畢就會釋放自動變量strongSelf不會對self進行一直進行強引用。

- (void)viewDidLoad {

    [super viewDidLoad];

    

    MyOBJ *mm = [[MyOBJ alloc]init];

    

    mm.name = @"Hanmeimei";

    __weak typeof(mm) weakSelf = mm;

    

    mm.doBlock = ^{

        __strong typeof(mm) strongSelf = weakSelf;

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSLog(@"my name is = %@",strongSelf.name);

        });

        

    };

    

    mm.doBlock();

}

//輸出:my name is = Hanmeimei

 

weakSelf 是爲了block不持有self,避免Retain Circle循環引用。
在 Block 內若是須要訪問 self 的方法、變量,建議使用 weakSelf。

strongSelf的目的是由於一旦進入block執行,假設不容許self在這個執行過程當中釋放,就須要加入strongSelf。block執行完後這個strongSelf 會自動釋放,不會存在循環引用問題。
若是在 Block 內須要屢次 訪問 self,則須要使用 strongSelf。

四、關於 多層嵌套的block
4.1單層block

- (void)doSomething{

    XXModel *model = [XXModel new];

    

    __weak typeof(self) weakSelf = self;

    

    model.dodoBlock = ^(NSString *title) {

        

        __strong typeof(self) strongSelf = weakSelf;

        strongSelf.titleLabel.text = title;

    };

    

    self.model = model;

}

 

- (void)viewDidLoad {

    [super viewDidLoad];

    [self doSomething];

}


4.2雙層block

- (void)setUpModel{

    XXModel *model = [XXModel new];

    

    __weak typeof(self) weakSelf = self;

    

    model.dodoBlock = ^(NSString *title) {

        

        __strong typeof(self) strongSelf = weakSelf;//第一層

        strongSelf.titleLabel.text = title;

        

        __weak typeof(self) weakSelf2 = strongSelf;

        strongSelf.model.dodoBlock = ^(NSString *title2) {

            

            __strong typeof(self) strongSelf2 = weakSelf2;//第二層

            strongSelf2.titleLabel.text = title2;

        };

    };

    

    self.model = model;

}


這樣就避免的引用循環,無論都多少個block嵌套,均可以按照這樣來作。

 

 

 

轉自:https://blog.csdn.net/nathan1987_/article/details/82749057

相關文章
相關標籤/搜索