dispatch_async(dispatch_get_main_queue(), ^{安全
[weakSelf updateView4SwiperSuccess:result];async
});
上面這段代碼,在 ARC有問題可是不會引發,由於weakSelf 釋放後會被置爲nil,OC語法向一個空的對象發送消息是不會崩潰的,雖然不會崩潰,可是原有邏輯卻走不了了。
在MRC下會出現野指針的狀況,即執行到block的時候,weakself 引用的self 已經釋放,而self 屬性是unsafe_unretained。因此這段block是不安全的。
那麼上面這段代碼如何正確的使用呢?函數
dispatch_async(dispatch_get_main_queue(), ^{spa
[self updateView4SwiperSuccess:result];指針
});
對你沒看錯,就是這樣使用,裏面不須要使用weakSelf。
block 引用self, self 引用計數+1,當block 執行完畢釋放時候self 引用計數減1,僞代碼以下code
dispatch_async(dispatch_get_main_queue(), ^{對象
//_Block_object_assingn(&self); self retain [self updateView4SwiperSuccess:result]; //_Block_object_dispose(&self); self release });
咱們要清楚的知道何時使用weakself,weakself是在有循環引用的狀況下使用的。即 a引用b,b也引用a。而GCD block裏面只引用了self ,self並無引用gcd 的block因此不須要用weakself。 下面示例的代碼也同樣。ip
NSObject *testObject = [[NSObject alloc] init];get
testObject.testBlock = ^(){ [self doSomeThing]; }; [testObject release];
上面這段代碼也不須要用weakself,很簡單 [testObject release];執行後 testObject 進度dealloc函數 釋放它的成員變量,包括testblock,testblock釋放調用函數_Block_object_dispose()釋放外部變量。因此不會循環引用,可是若是上面代碼寫成這樣就會出現循環引用了it
-(void)test
self.testObject = [[NSObject alloc] init]; self.testObject.testBlock = ^(){ [self doSomeThing]; };
}
(void)dealloc
{
self.testObject = nil;
}
上面這段函數就出現了循環引用,self,等待testobject釋放,而testobject也在等待self釋放,這樣就形成了循環引用。對於上面這段代碼循環引用的原理我就不詳細解釋了。(轉)