天天看點

strong、weak、copy、retain和assign的差別

assign:

assign

一般用來修飾基本的資料類型,包括基礎資料類型(NSInteger,CGFloat)和C語言資料類型(int,float,double,char)等等。因為assign聲明的屬性,是不會增加引用計數的,也就是說聲明的屬性釋放後也就沒有了,及時其他對象引用了它也不會保留,隻會造成crash。但是及時被釋放,指針卻還在,成為了

野指針

,如果新的對象被配置設定到了這個記憶體位址上,又會造成crash。是以一般隻用來聲明基本的資料類型,因為它們會被配置設定到

棧區

上,而棧取由系統

自動管理

,不會造成野指針。

retain:

與assign相對,我們要解決

對象

被其他對象引用後釋放造成的問題,就需要用

retain

來聲明。使用retain聲明的對象會

更改引用計數

,每次被引用,引用計數都會

+1

,釋放後就會

-1

。即使這個對象本身被釋放了,隻要還有對象在引用它,該對象就會

仍然持有

,不會出現任何問題。并且隻有當引用

計數為0時

,就會被

dealloc

析構函數回收進記憶體。

copy:

最常見到的copy的聲明使用是 NSString 等。copy與retain的

差別

在于:retain是拷貝記憶體指針位址,而copy是拷貝對象本身;也就是說retain是

淺複制

,copy是

深複制

;如果是淺複制,當修改對象值時,都會被修改,而深複制不會。之是以在

NSString

這一類有

可變類型對象

的身上使用

copy

關鍵字,是因為他們有可能和對應的可變類型如

NSMutableString

之間進行指派操作,為了防止内容被改變,使用copy去深複制一份。copy工作由copy方法執行,此屬性隻對那些實作了

NSCopying

協定的

對象類型

有效。

weak:

weak是由ARC新引入的對象變量屬性,weak類似于assign,叫

弱引用

,也是不增加引用計數,不同在于week指向對象類型時,當對象被釋放會指向nil,而assign則會造成野指針。一般隻有在防止循環引用時候使用;比如父類引用了子類,子類又引用父類;IBOutlet、Delegate等一般就是使用week,這是因為他們可能會在類外部被調用,防止循環應用。

strong:

strong也是由ARC新引入的對象變量屬性,在ARC下,用strong代替了retain,叫

強引用

,會增加引用計數。,所有的局部變量代碼中我們聲明的變量預設都是強引用,不需要再額外使用

__strong

來修飾。

什麼時候用

stong

/

weak

  • 根視圖和父視圖需要使用

    strong

    ; 子視圖使用

    weak

  • 沒有強指針指向的對象使用

    strong

    ; 有強指針指向的可以可以

    weak

__strong,__weak,__unsafe_unretained,__autoreleasing

的含義

在ARC情況下,對象類型的變量将有所有權修飾符

__strong

: 是預設的關鍵詞。

__weak

: 聲明了一個可以自動nil化的引用。

__unsafe_unretained

: 聲明一個弱引用,但是不會自動nil化,也就是說,如果所指向的記憶體區域被釋放了,這個指針就是一個野指針了。

__autoreleasing

: 用來修飾一個函數的參數,這個參數在函數傳回的時候會被自動釋放。

ARC

聲明屬性時,對于

基本資料類型

預設關鍵字是 (atomic,readwrite,assign)

ARC

聲明屬性時,對于普通的

OC對象

預設關鍵字是 (atomic,readwrite,strong)

  • 示例

擴充:

LLVM官網給出的一些示意,ARC裡也可以使用retain等關鍵字

assign 等同于unsafe_retained

copy的作用和MRC一樣,同時又有strong的效果

retain等同于strong

weak和unsafe_unretained的差別在于:weak降被釋放指針指派為nil,而unsafe_unretained則會成為野指針