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
stong
weak
- 根視圖和父視圖需要使用
; 子視圖使用strong
weak
- 沒有強指針指向的對象使用
; 有強指針指向的可以可以strong
weak
__strong,__weak,__unsafe_unretained,__autoreleasing
的含義
__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則會成為野指針