一、關於__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