ARC下,我們常常會使用weak 的修飾符來修飾一個變量,防止其在block中被循環引用,但是有些特殊情況下,有必要在block中使用strong 來修飾這個在block外剛剛用__weak修飾的變量,這樣寫有什么必要性呢?
首先結合代碼看一下在block外使用__weak修飾的情況:
clang -rewrite-objc QYTestOject.m
將OC代碼轉成C++,可以看到block的底層實現:
2是調用block具體執行的代碼段;
3表示的就是-(void)test這個函數
在執行3的時候,會調用到2,可以看到在2中__cself是__QYTestObject__test_block_imp1_0對象,也就是代碼中的block自身,2中__cself->weakSelf,可以看出block將weakSelf作為自己的屬性來使用,而weakSelf保存有指向self的引用,但是self的引用計數并沒有增加,所以self依然可以被釋放,這樣就保證了不會出現循環引用,那為什么蘋果還提倡weak,strong的寫法呢?首先看一下代碼:
對應的c++代碼:
attribute((objc_ownership(strong))) typeof(self) strongSelf = weakSelf;
從這行代碼可以看到在block內部又強引用了self,那這樣不會造成循環引用嗎?
strongSelf在block內部是作為局部變量,strongSelf也不屬于block結構體的屬性,一旦block執行結束,局部變量就會被釋放,所以strongSelf不會引起循環引用。
假設僅僅使用weakSelf持有一次對self的弱引用,如果self在其他地方不小心被釋放,weakSelf也變成了nil,block可能無法繼續執行,程序將會崩潰。
這樣做的意義在于可以保證在block執行期間,self不會被釋放,而block執行結束之后,self可以正常被釋放,不會引起循環引用,所以weakSelf與strongSelf意義是不一樣的,一內一外,保證程序正常運行。