修飾詞:assign、weak、strong、retain、copy、nonatomic、atomic、readonly、readwrite
assign(ARC、MRC)
1、修飾整型等基本數(shù)據(jù)類型,直接賦值的意思。
2、如果沒有weak、strong、retain、copy修飾,默認(rèn)使用assign。
3、對象也可以用assign修飾,只是引用計(jì)數(shù)不會+1(與strong的區(qū)別)
4、如果用來修飾對象屬性,對象銷毀后是不會指向nil的,就會產(chǎn)生野指針錯誤。(與weak的區(qū)別)
weak(ARC)(對象)
1、針對對象的修飾詞,不能修飾基本數(shù)據(jù)類型(int float)
2、weak修飾的引用計(jì)數(shù)不會+1,也是直接賦值
3、弱引用是為了打破循環(huán)引用而產(chǎn)生的。
比如:在block中,block在copy的時候,會對內(nèi)部使用到的對象引用計(jì)數(shù)+1,,如果使用[self 方法名],那么就會有一個強(qiáng)指針指向self所在的class的內(nèi)存地址,class的引用計(jì)數(shù)+1,這樣導(dǎo)致class所在的內(nèi)存地址無法被釋放,造成內(nèi)存泄露
4、指針指向的對象如果被銷毀,指針會指向nil,不會產(chǎn)生野指針錯誤。
weak 和 assign的區(qū)別
assign與weak,它們都是弱引用聲明類型
1.用weak聲明的變量在棧中就會自動清空,賦值為nil。
2.用assign聲明的變量在棧中可能不會自動賦值為nil,就會造成野指針錯誤!
以delegate的聲明為例,在MRC中多delegate聲明使用的是assign,這是為了不造成循環(huán)引用,這時,我們需要在-dealloc方法中寫上 self.delegate = nil,以免造成delegate的野指針錯誤。當(dāng)然,在ARC中,只需要用weak聲明delegate,就會自動釋放了。
strong ( ARC )(對象)
1.直接賦值并且對象的引用計(jì)數(shù)器 +1 .
2.在 ARC 里替代了 retain 的作用 .
retain ( MRC )
1.release 舊對象( 舊對象計(jì)數(shù)器 -1 ) , retain 新對象( 新對象計(jì)數(shù)器 +1 ) , 然后指向新對象 .
2.在set方法里面是這樣的 :
```
if(_dog!=nil) {
? [_dogrelease];?
}
_dog= [dog retain];
```
copy ( ARC/MRC )
1.copy 在 MRC 時是這樣做的 release 舊對象( 舊對象的引用計(jì)數(shù)器 -1 ) , copy 新對象( 新對象的引用計(jì)數(shù)器 +1 ) , 然后指向新對象 .(新對象是指最終指向的那個對象,不管深拷貝還是淺拷貝)
1.1在set方法里面是這樣的 :
```
if (_dog != nil) {
[_dog release];
}
_dog = [dog copy];
2.copy 在 ARC 時是這么干的 copy 新對象( 新對象的引用計(jì)數(shù)器 +1 ) , 然后指向新對象 .
2.1在set方法里面是這樣的 :
```
_dog = [dog copy];
```
3.使用注意 :
3.1 修飾的屬性本身要不可變的。
例如 NSMutableArray 采用 copy 修飾 , 在addObject時會出現(xiàn)Crash, 因?yàn)镹SMutableArray的對象在copy 過后就會變成NSArray。如果需要copy NSMutableArray對象,用:mutablecopy。
3.2 遵守 NSCopying 協(xié)議的對象使用 .
nonatomic ( ARC/MRC )
1.不對set方法加同步鎖 .
2.性能好
3.線程不安全
atomic ( ARC/MRC )
1.原子屬性就是對生成的 set 方法加互斥鎖 @synchronized(鎖對象) .
```
@synchronized(self) { _delegate = delegate;}
```
2.需要消耗系統(tǒng)資源 .
3.互斥鎖是利用線程同步實(shí)現(xiàn)的 , 意在保證同一時間只有一個線程調(diào)用 set 方法 .
4.其實(shí)還有 get 方法 , 要是同時 set 和 get 一起調(diào)用還是會有問題的 . 所以即使用了 atomic 修飾 還是不夠安全 .
nonatomic 和 atomic 的介紹和區(qū)別
1. 什么是atomicity(原子性)?
atomicity(原子性):我把原子性理解成線程對屬性的單一執(zhí)行。
例如,當(dāng)兩條線程同時執(zhí)行一個屬性的set方法的時候,如果不具有原子性(也就是聲明屬性時使用了nonatimic),那么就可能出現(xiàn)當(dāng)A線程正在改寫某屬性值的時候,B線程也許會突然闖入,把尚未修改好的屬性值讀取出來。發(fā)生這種情況時,線程讀取到的屬性值肯能不對。
2. 保證atomicity真的就線程安全了嗎?為什么日常聲明都用的是nonatomic呢?
1.保證atomicity并非也是線程安全的,如果需要保證安全,需要跟深層次的線程鎖定機(jī)制。
2.使用同步鎖在iOS中開銷比較大,會給程序帶來性能上的問題。
3. 為什么atomicity也不能保證線程安全?
例如:當(dāng)使用atomic時,仍然可能出現(xiàn)線程錯誤:當(dāng)線程A進(jìn)行set操作,這時其他線程的get或者set操作會因?yàn)榈仍摬僮鞫却?。?dāng)A線程的set操作結(jié)束后,B線程進(jìn)行set操作,然后當(dāng)A線程需要get操作時,卻獲得了在B線程的值,這就破壞了線程安全,如果有C線程在A線程get操作之前release了該屬性,那么還會導(dǎo)致程序崩潰。所以僅僅使用atomic并不會使得線程安全,我們還是要為線程添加lock來確保線程的安全。
readonly (只讀)
1.讓 Xcode 只生成get方法 .
2.不想把暴露的屬性被人隨便替換時 , 可以使用 .
readwrite (讀寫)(默認(rèn))
1.讓 Xcode 生成get/set方法 .
2.不用 readonly 修飾時 , 默認(rèn)就是 readwrite .