一、__block理解: Blocks可以訪問局部變數,但是不能修改, 聲明block的時候實際上是把當時的臨時變數又複製了一份, 在block里即使修改了這些複製的變數,也不影響外面的原始變數。即所謂的閉包。 如果修改局部變數,需要加__block。 API Reference對__block變數 ...
一、__block理解:
Blocks可以訪問局部變數,但是不能修改,
聲明block的時候實際上是把當時的臨時變數又複製了一份,
在block里即使修改了這些複製的變數,也不影響外面的原始變數。即所謂的閉包。
如果修改局部變數,需要加__block。
API Reference對__block變數修飾符有如下幾處解釋
//A powerful feature of blocks is that they can modify variables in the same lexical scope. You signal that a block can modify a variable using the __block storage type modifier. //At function level are __block variables. These are mutable within the block (and the enclosing scope) and are preserved if any referencing block is copied to the heap.
大概意思歸結出來就是兩點:
1.__block對象在block中是可以被修改、重新賦值的。
2.__block對象在block中不會被block強引用一次,從而不會出現迴圈引用問題。
二、__weak的理解
__weak __typeof(&*self)weakSelf =self; 等同於
__weak UIViewController *weakSelf =self;
為什麼不用__block 是因為通過引用來訪問self的實例變數 ,self被retain,block也是一個強引用,
引起迴圈引用,用__week是弱引用,當self釋放時,weakSelf已經等於nil。
API Reference對__weak變數修飾符有如下幾處解釋:
__weak specifies a reference that does not keep the referenced object alive. A weak reference is set to nil when there are no strong references to the object.
使用了__weak修飾符的對象,作用等同於定義為weak的property。自然不會導致迴圈引用問題,因為蘋果文檔已經說的很清楚,當原對象沒有任何強引用的時候,弱引用指針也會被設置為nil。
因此,__block和__weak修飾符的區別其實是挺明顯的:
1.__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本數據類型。
2.__weak只能在ARC模式下使用,也只能修飾對象(NSString等),不能修飾基本數據類型(int)。
3.__block對象可以在block中被重新賦值,__weak不可以。
PS:__unsafe_unretained修飾符可以被視為iOS SDK 4.3以前版本的__weak的替代品,不過不會被自動置空為nil。所以儘可能不要使用這個修飾符。
總之,_block & _weak:
在block代碼塊中也會用類似代碼來修飾變數,
__block 為了改變block代碼塊外部的變數。例如:你在外面定義了一個整形變數,想要在block塊內改變他,那麼,就要用__block 來修飾這個整形變數。
__weak 是為了防止迴圈引用,引起記憶體泄露的問題。 例如: __weak ViewController *wself = self;