weak與assign
一、什么情況下使用 weak 關(guān)鍵字?
1、ARC中,在有可能出現(xiàn)循環(huán)引用的時候,往往要通過讓其中一端使用weak來解決,比如:delegate 的代理屬性。
2、自身已經(jīng)對它有過一次強引用,所以沒有必要再強引用一次。這個時候也會使用weak;還有就是自定義IBOutlet控件屬性一般也使用weak,一般情況也可以使用strong。
二、weak和assign有什么不同?
1、weak的特質(zhì)表明,該屬性定義了一種“非擁有關(guān)系” (nonowning relationship)。為這種屬性設(shè)置新值時,設(shè)置方法既不保留新值,也不釋放舊值,但是weak修飾的對象被摧毀時,屬性值也會清空(nil out)。assign的setter方法只會執(zhí)行簡單賦值操作。
2)assign可以用于非OC對象;weak必須用于OC對象,如果修飾基本數(shù)據(jù)類型,編譯器會報錯-“Property with ‘weak’ attribute must be of object type”。MRC下,使用unsafe_unretained修飾對象類型。unsafe_unretained也可能產(chǎn)生野指針,所以它名字是"unsafe_”。
2.是否產(chǎn)生野指針的區(qū)別
weak 不會產(chǎn)生野指針問題。因為weak修飾的對象釋放后(引用計數(shù)器值為0),指針會自動被置nil,之后再向該對象發(fā)消息也不會崩潰。 weak是安全的。
assign 如果修飾對象,會產(chǎn)生野指針問題;如果修飾基本數(shù)據(jù)類型則是安全的。修飾的對象釋放后,指針不會自動被置空,此時向?qū)ο蟀l(fā)消息會崩潰。
weak引用表原理:
https://www.cnblogs.com/doudouyoutang/p/9952026.html
https://www.cnblogs.com/yangwenhuan/p/9226689.html
http://yulingtianxia.com/blog/2015/12/06/The-Principle-of-Refenrence-Counting/
copy和strong
strong此特質(zhì)標(biāo)明該屬性定義了一種擁有關(guān)系。為這種屬性設(shè)定新值時,設(shè)置方法會先保留新值再釋放舊值,然后再講新值設(shè)置上去。
copy 此特質(zhì)所表達的所屬關(guān)系與strong類似。然而設(shè)置方法并不保留新值而是將其拷貝,當(dāng)屬性類型為NSString*時,經(jīng)常用此特性來保護其封裝性,因為傳遞給設(shè)置方法的新值有可能指向一個NSMutableString類的實例這個類是NSString的子類,表示一種可以修改其值得字符串,此時若是不拷貝字符串,那么設(shè)置完屬性之后,字符串的值就可能會在對象不知情的情況下遭人更改。所以這時就要拷貝一份不可變的字符串,確保對象中的字符串值不會無意間變動。只要實現(xiàn)屬性所用的對象是可變的,就應(yīng)該在設(shè)執(zhí)行屬性是拷貝一份
atomic和nonatomic
*atomic只是保證了getter/setter存取方法的線程安全.并不能保證整個對象是線程安全的,因此在多線程編程時,線程安全還需要開發(fā)者自己來處理。
*atomic系統(tǒng)生成的getter/setter會保證get/set操作的安全性,但相對nonatomic來說,atomic會更耗費資源,且速度要慢,故在iPhone等小型設(shè)備上,如果沒有多線程之間的通訊,使用nonatomic是更好的選擇。
此處可以引出鎖的問題(鎖用于解決線程爭奪資源的問題,一般分為兩種,自旋鎖(spin)和互斥鎖(mutex)):
iOS10之前atomic使用的是自旋鎖,但是iOS 10之后,蘋果因為一個巨大的缺陷棄用了 OSSpinLock 改為新的 os_unfair_lock。
新版 iOS 中,系統(tǒng)維護了 5 個不同的線程優(yōu)先級/QoS: background,utility,default,user-initiated,user-interactive。高優(yōu)先級線程始終會在低優(yōu)先級線程前執(zhí)行,一個線程不會受到比它更低優(yōu)先級線程的干擾。這種線程調(diào)度算法會產(chǎn)生潛在的優(yōu)先級反轉(zhuǎn)問題,從而破壞了 spin lock。(描述引用自 ibireme 大神的文章:不再安全的 OSSpinLock)