一、atomic與nonatomic
1.相同點
都是為對象添加get和set方法
2.不同點
atomic為get方法加了一把安全鎖(及原子鎖),使得方法get線程安全,執行效率慢
nonatomic沒有添加安全鎖,執行效率快
一般iOS程序中,所有屬性都聲明為nonatomic。這樣做的原因是:
在iOS中使用同步鎖的開銷比較大, 這會帶來性能問題。一般情況下並不要求屬性必須是“原子的”,因為這並不能保證“線程安全”(thread safety),若要實現“線程安全”的操作,還需采用更為深層的鎖定機制才醒。
例如:一個線程在連續多次讀取某個屬性值的過程中有別的線程在同時改寫該值,那么即便將屬性聲明為atomic,也還是會讀取到不同的屬性值。
二、assign,copy與retain
assign: 簡單賦值,不更改索引計數(Reference Counting)。
copy: 建立一個索引計數為1的對象,然后釋放舊對象
retain:釋放舊的對象,將舊對象的值賦予輸入對象,再提高輸入對象的索引計數為1
這里做一個簡單的隱喻:
在系統內存中malloc 創建了一個房子A(及為對象分配內存),我A的地址告訴管理者a,(A房子管理者數+1)
情況1、assign b來的情況,由於是弱對象,管理a只能給b間接使用權,不告訴它地址,所以管理者還是只有a一個,這個時候因為b是弱對象,a如果離開了,A這個房子就沒管理者了。A房子就會被系統收回,b成為野孩子了,野孩子亂找內存操作容易導致系統奔潰。
情況2、retain c 來的情況,c擁有一個地址拷貝技能,拷貝了a知道的A房子的地址住所,然后把a謀殺了,系統(A房子管理者數-1),同時c成為新的管理者(A房子管理者數+1)
情況3、copy d來的情況,d有一個好的技能,看到好的東西立馬拷貝一份專屬自己的,d給拷貝來的新房子命名成D,系統划分了一個新的底盤給d(D房子管理者數+1),然后d把a也謀殺了,(A房子管理者數-1),A房子沒有管理者,系統回收了A房子這塊地
三、weak 和strong的區別:
(weak和strong)不同的是 當一個對象不再有strong類型的指針指向它的時候 它會被釋放 ,即使還有weak型指針指向它。
一旦最后一個strong型指針離去 ,這個對象將被釋放,所有剩余的weak型指針都將被清除。
可能有個例子形容是妥當的。
想象我們的對象是一條狗,狗想要跑掉(被釋放)。
strong型指針就像是栓住的狗。只要你用牽繩掛住狗,狗就不會跑掉。如果有5個人牽着一條狗(5個strong型指針指向1個對象),除非5個牽繩都脫落 ,否着狗是不會跑掉的。
weak型指針就像是一個小孩指着狗喊到:“看!一只狗在那” 只要狗一直被栓着,小孩就能看到狗,(weak指針)會一直指向它。只要狗的牽繩脫落,狗就會跑掉,不管有多少小孩在看着它。
只要最后一個strong型指針不再指向對象,那么對象就會被釋放,同時所有的weak型指針都將會被清除。
使用建議:
當用copy時,set方法會先release舊值,再copy一個新的對象,reference count 為1(減少了對上下文的依賴);當用assign,直接賦值,無retain操作。當用retain,release舊值,retain新值;
非ARC
• 1> copy : 只用於NSString\block
• 2> retain : 除NSString\block以外的OC對象
• 3> assign : 基本數據類型、枚舉、結構體(非OC對象),當2個對象相互引用,一端用retain,一端用assign
•2.ARC
• 1> copy : 只用於NSString\block
• 2> strong : 除NSString\block以外的OC對象
• 3> weak : 當2個對象相互引用,一端用strong,一端用weak
4> assgin : 基本數據類型、枚舉、結構體(非OC對象)
NSString、NSArray、NSDictionary 等等經常使用copy關鍵字,是因為他們有對應的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary;
block 使用 copy 是從 MRC 遺留下來的“傳統”,在 MRC 中,方法內部的 block 是在棧區的,使用 copy 可以把它放到堆區.在 ARC 中寫不寫都行:對於 block 使用 copy 還是 strong 效果是一樣的,但寫上 copy 也無傷大雅,還能時刻提醒我們:編譯器自動對 block 進行了 copy 操作。如果不寫 copy ,該類的調用者有可能會忘記或者根本不知道“編譯器會自動對 block 進行了 copy 操作”,他們有可能會在調用之前自行拷貝屬性值。這種操作多余而低效。
下面做下解釋: copy 此特質所表達的所屬關系與 strong 類似。然而設置方法並不保留新值,而是將其“拷貝” (copy)。 當屬性類型為 NSString 時,經常用此特質來保護其封裝性,因為傳遞給設置方法的新值有可能指向一個 NSMutableString 類的實例。這個類是 NSString 的子類,表示一種可修改其值的字符串,此時若是不拷貝字符串,那么設置完屬性之后,字符串的值就可能會在對象不知情的情況下遭人更改。所以,這時就要拷貝一份“不可變” (immutable)的字符串,確保對象中的字符串值不會無意間變動。只要實現屬性所用的對象是“可變的” (mutable),就應該在設置新屬性值時拷貝一份。
用@property 聲明 NSString、NSArray、NSDictionary 經常使用 copy 關鍵字,是因為他們有對應的可變類型:NSMutableString、NSMutableArray、NSMutableDictionary,他們之間可能進行賦值操作,為確保對象中的字符串值不會無意間變動,應該在設置新屬性值時拷貝一份。
單獨介紹下copy使用Nsstring
推薦這個博客,解釋詳細http://blog.csdn.net/itianyi/article/details/9018567
引用里面的第一句話其實說白了,對字符串為啥要用這兩種方式?我覺得還是一個安全問題,比如聲明的一個NSString *str變量,然后把一個NSMutableString *mStr變量的賦值給它了,如果要求str跟着mStr變化,那么就用retain;如果str不能跟着mStr一起變化,那就用copy。而對於要把NSString類型的字符串賦值給str,那兩都沒啥區別。不會影響安全性,內存管理也一樣。