關(guān)于iOS中strong,weak,retain,assign,copy,nomatic

iOS 5之后添加了ARC的特性,順便提出來(lái)新的strong、weak關(guān)鍵字。相比而言,retain和strong是一致的(聲明為強(qiáng)引用);assign和weak是基本一致的(聲明為弱引用)。

之所以說(shuō)它倆是基本一致是因?yàn)樗鼈z還是有所不同的,weak嚴(yán)格的說(shuō)應(yīng)當(dāng)叫“歸零弱引用”,即當(dāng)對(duì)象被銷毀后,會(huì)自動(dòng)的把它的指針置為nil,這樣可以防止野指針錯(cuò)誤。而assign銷毀對(duì)象后不會(huì)把該對(duì)象的指針置nil,對(duì)象已經(jīng)被銷毀,但指針還在癡癡的指向它,這就成了野指針,這是比較危險(xiǎn)的。

1、引用計(jì)數(shù)

在ObjC中每個(gè)對(duì)象內(nèi)部都有一個(gè)與之對(duì)應(yīng)的整數(shù)(retainCount),叫“引用計(jì)數(shù)器”,當(dāng)一個(gè)對(duì)象在創(chuàng)建之后它的引用計(jì)數(shù)器為1,當(dāng)調(diào)用這個(gè)對(duì)象的alloc、retain、new、copy方法之后引用計(jì)數(shù)器自動(dòng)在原來(lái)的基礎(chǔ)上加1(ObjC中調(diào)用一個(gè)對(duì)象的方法就是給這個(gè)對(duì)象發(fā)送一個(gè)消息),當(dāng)調(diào)用這個(gè)對(duì)象的release方法之后它的引用計(jì)數(shù)器減1,如果一個(gè)對(duì)象的引用計(jì)數(shù)器為0,則系統(tǒng)會(huì)自動(dòng)調(diào)用這個(gè)對(duì)象的dealloc方法來(lái)銷毀這個(gè)對(duì)象。

2、內(nèi)容與場(chǎng)景
關(guān)鍵字 內(nèi)容 場(chǎng)景
assign 默認(rèn)類型,setter方法直接賦值,不進(jìn)行任何retain操作,不改變引用計(jì)數(shù) 對(duì)基礎(chǔ)數(shù)據(jù)類型(NSInteger)和C數(shù)據(jù)類型(int,float,double,char等)
retain 釋放舊的對(duì)象(release),將舊對(duì)象的值賦給新對(duì)象,再令新對(duì)象引用計(jì)數(shù)為1 對(duì)其他NSObject和其子類
copy 與retain處理流程一樣,先對(duì)舊值release,再copy出新的對(duì)象,retainCount為1. 對(duì)NSString
nonatomic 非原子性訪問(wèn),對(duì)屬性賦值的時(shí)候不加鎖,多線程并發(fā)訪問(wèn)會(huì)提高性能 如果不加此屬性,則默認(rèn)是兩個(gè)訪問(wèn)方法都為原子型事務(wù)訪問(wèn)

【注】對(duì)copy屬性要特別注意:被定義有copy屬性的對(duì)象必須要 符合NSCopying協(xié)議,必須實(shí)現(xiàn)- (id)copyWithZone:(NSZone *)zone方法。

具體一點(diǎn):IBOutlet可以為weak,NSString為copy,Delegate一般為weak,其他的看情況。一般來(lái)說(shuō),類“內(nèi)部”的屬性設(shè)置為strong,類“外部”的屬性設(shè)置為weak。說(shuō)到底就是一個(gè)歸屬權(quán)的問(wèn)題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無(wú)法釋放。

3、比較

|strong vs weak |
| :--- -------------|
| strong:強(qiáng)引用,也是我們通常說(shuō)的引用,其存亡直接決定了所指向?qū)ο蟮拇嫱觥H绻淮嬖谥赶蛞粋€(gè)對(duì)象的引用,并且此對(duì)象不再顯示在列表中,則此對(duì)象會(huì)被從內(nèi)存中釋放|
| weak:弱引用,不決定對(duì)象的存亡。即使一個(gè)對(duì)象被持有無(wú)數(shù)個(gè)弱引用,只要沒(méi)有強(qiáng)引用指向它,那么還是會(huì)被清除 |
|strong與retain功能相似;weak與assign相似,只是當(dāng)對(duì)象消失后weak會(huì)自動(dòng)把指針變?yōu)閚il,防止野指針|
【注】有一種情況你需要使用weak(默認(rèn)是strong),就是為了避免retain cycles(就是父類中含有子類{父類retain了子類},子類中又調(diào)用了父類{子類又retain了父類},這樣都無(wú)法release)

|copy vs retain |
| :--- -------------|
| copy其實(shí)是建立了一個(gè)相同的對(duì)象,而retain不是|
|copy是內(nèi)容拷貝,retain是指針拷貝|
|copy是內(nèi)容的拷貝 ,對(duì)于像NSString,的確是這樣,如果拷貝的是NSArray,這時(shí)只是copy了指向array中相對(duì)應(yīng)元素的指針.這便是所謂的"淺復(fù)制"|
【注】copy是在你不希望a和b共享一塊內(nèi)存時(shí)會(huì)使用到,a和b各自有自己的內(nèi)存。

|強(qiáng)引用 vs 弱引用 |
| :--- -------------|
| 強(qiáng)引用:當(dāng)前對(duì)象被其他對(duì)象引用時(shí),會(huì)執(zhí)行retain操作,引用計(jì)數(shù)器+1。當(dāng)retainCount=0時(shí),該對(duì)象才會(huì)被銷毀。因?yàn)槲覀円M(jìn)行對(duì)象的內(nèi)存管理,所以這是默認(rèn)的引用方式。(默認(rèn)是強(qiáng)引用)|
|弱引用:當(dāng)前對(duì)象的生命周期不被是否由其他對(duì)象引用限制,它本該什么時(shí)候銷毀就什么時(shí)候被銷毀。即使它的引用沒(méi)斷,但是當(dāng)它的生存周期到了時(shí)就會(huì)被銷毀。|
【注】在定義屬性時(shí),若聲明為retain類型的,則就是強(qiáng)引用;若聲明為assign類型的,則就是弱引用。后來(lái)內(nèi)存管理都由ARC來(lái)完成后,若是強(qiáng)引用,則就聲明為strong;若是弱引用,則就聲明為weak。

|__block和__weak修飾符|
| :--- -------------|
|__block不管是ARC還是MRC模式下都可以使用,可以修飾對(duì)象,還可以修飾基本數(shù)據(jù)類型|
|__weak只能在ARC模式下使用,也只能修飾對(duì)象(NSString),不能修飾基本數(shù)據(jù)類型(int)|
|__block可以在block對(duì)象中被重新賦值 (_weak不可以) |

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容