強(qiáng)引用和弱引用:
特點(diǎn):
在強(qiáng)引用中,有時(shí)會(huì)出現(xiàn)循環(huán)引用的情況狼钮,這時(shí)就需要弱引用來(lái)幫忙(__weak)碳柱。
強(qiáng)引用持有對(duì)象,弱引用不持有對(duì)象熬芜。
強(qiáng)引用可以釋放對(duì)象莲镣,但弱引用不可以,因?yàn)槿跻貌怀钟袑?duì)象涎拉,當(dāng)弱引用指向一個(gè)強(qiáng)引用所持有的對(duì)象時(shí)瑞侮,當(dāng)強(qiáng)引用將對(duì)象釋放掉后,弱引用會(huì)自動(dòng)的被賦值為nil鼓拧,即弱引用會(huì)自動(dòng)的指向nil半火。
我們已經(jīng)知道OC中的內(nèi)存管理是通過(guò)“引用計(jì)數(shù)器”來(lái)實(shí)現(xiàn)的。一個(gè)對(duì)象的生命周期取決于它是否還被其他對(duì)象引用(是否retainCount=0)季俩。但在有些情況下钮糖,我們并不希望對(duì)象的銷毀時(shí)間由是否被其他對(duì)象引用來(lái)決定,而是這個(gè)對(duì)象本該是什么時(shí)候銷毀就什么時(shí)候被銷毀酌住。這時(shí)店归,我們得引入“強(qiáng)引用”和“弱引用”的概念。
強(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轨淌。
所以說(shuō),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)的。
避免“強(qiáng)引用循環(huán)“的僵局:
默認(rèn)的引用方式是強(qiáng)引用拓颓,但上面說(shuō)了有時(shí)我們還得使用弱引用语婴,那是什么情況呢描孟?
答案驶睦,強(qiáng)引用循環(huán):A對(duì)象強(qiáng)引用了B對(duì)象,B對(duì)象也強(qiáng)引用了A匿醒。因?yàn)槎际菑?qiáng)引用场航,也就是無(wú)論是A是B都要在對(duì)方的引用斷了后才能銷毀,但要斷了引用廉羔,就必須對(duì)方對(duì)象銷毀溉痢。就會(huì)出現(xiàn)這種僵局,為了避免出現(xiàn)這種情況,就應(yīng)該有一個(gè)對(duì)象“示弱”孩饼,使其為“弱引用”髓削。
比較常見(jiàn)的,視圖中的父子視圖之間的引用:父視圖強(qiáng)引用子視圖镀娶,子視圖弱引用父視圖立膛。
總結(jié):由于要進(jìn)行內(nèi)存管理的緣故,OC里的引用默認(rèn)都是強(qiáng)引用梯码,但為了避免出現(xiàn)”強(qiáng)引用循環(huán)僵局“宝泵,所以有了弱引用(assign)。
retain和strong都是 指針拷貝轩娶。 當(dāng)有其他對(duì)象引用當(dāng)前對(duì)象時(shí)儿奶,會(huì)拷貝一份當(dāng)前對(duì)象的地址,這樣它就也指向當(dāng)前對(duì)象了鳄抒。所以闯捎,還是同一個(gè)對(duì)象,只是retainCount+1嘁酿;
而copy則是 內(nèi)容拷貝隙券。 是實(shí)實(shí)在在的拷貝一個(gè)新的對(duì)象,拷貝了它的內(nèi)存內(nèi)容闹司,成為一個(gè)新的對(duì)象(retainCount=1)娱仔。
深拷貝(mutableCopy)和淺拷貝(copy):
深拷貝就是內(nèi)容拷貝,淺拷貝就是指針拷貝游桩。
在OC中牲迫,若要進(jìn)行對(duì)象的拷貝,則該對(duì)象所屬的類必須遵守NSCopying和NSMutableCopy協(xié)議借卧,并重寫copyWithZone:和mutableCopyWithZone:方法盹憎。而系統(tǒng)原生類,之所以可以直接進(jìn)行拷貝是因?yàn)樗褞臀覀冏詣?dòng)做了這些事铐刘。