天天看點

__weak 和 __block 關鍵字的差別

問題描述:在使用block 時,為避免親戚循環引用問題,我們一般常将外部變量用 __weak 或者 __block 關鍵字進行修飾。那麼二者的差別在哪呢?

下面引自官方的說明:

From the docs about __block

__block variables live in storage that is shared between the lexical scope of the variable and all blocks and block copies declared or created w

So they are technically different things. __block is to stop your variable being copied from your external scope into your block scope. __weak is a self delimiting weak pointer.

From the docs about __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.

So they are technically different things. __block is to stop your variable being copied from your external scope into your block scope. __weak is a self delimiting weak pointer.

Note I said technically, because for your case they will do (almost) the same thing. The only difference is if you are using ARC or not. If your project uses ARC and is only for iOS4.3 and above, use __weak. It ensures the reference is set to nil if the global scope reference is releases somehow. If your project doesn't use ARC or is for older OS versions, use __block.

There is a subtle difference here, make sure you understand it.

EDIT: Another piece to the puzzle is __unsafe_unretained. This modifier is almost the same as __weak but for pre 4.3 runtime environments. HOWEVER, it is not set to nil and can leave you with hanging pointers.

AIn manual reference counting mode, __block id x; has the effect of not retaining x. In ARC mode, __block id x; defaults to retaining x (just like all other values). To get the manual reference counting mode behavior under ARC, you could use __unsafe_unretained __block id x;. As the name __unsafe_unretained implies, however, having a non-retained variable is dangerous (because it can dangle) and is therefore discouraged. Two better options are to either use __weak (if you don’t need to support iOS 4 or OS X v10.6), or set the __block value to nil to break the retain cycle.

自我總結一下就是:

1,在MRC 時代,__block 修飾,可以避免循環引用;ARC時代,__block 修飾,同樣會引起循環引用問題;

2,__block不管是ARC還是MRC模式下都可以使用,可以修飾對象,還可以修飾基本資料類型;

3,__weak隻能在ARC模式下使用,也隻能修飾對象,不能修飾基本資料類型;

4,__block對象可以在block中被重新指派,__weak不可以;

5,__unsafe_unretained修飾符可以被視為iOS SDK 4.3以前版本的__weak的替代品,不過不會被自動置空為nil。是以盡可能不要使用這個修飾符。(__weak 會自動置為nil)