weak:簡(jiǎn)單來(lái)講是弱引用哼丈。引用計(jì)數(shù)器不會(huì)加一,并在引用對(duì)象被釋放的時(shí)候自動(dòng)被設(shè)置為nil筛严。通常用于解決循環(huán)引用問(wèn)題醉旦。適用于delegate和block
Strong:強(qiáng)引用。MRC下引用計(jì)數(shù)器會(huì)加一,默認(rèn)所有實(shí)例變量和局部變量都是Strong指針
Copy:也是強(qiáng)引用髓抑,但是引用計(jì)數(shù)器不會(huì)加一咙崎。
Assign:assign一般用于基本數(shù)據(jù)類型,無(wú)引用計(jì)數(shù)器吨拍。這種類型是放在棧中的褪猛,由系統(tǒng)來(lái)控制創(chuàng)建和銷毀。也可以用于對(duì)象羹饰,但是用于對(duì)象并不會(huì)引用計(jì)數(shù)伊滋,如果你用它修飾對(duì)象,那么他會(huì)放在堆中队秩,由我們自己來(lái)控制銷毀笑旺,而他又是弱類型。所以很容易造成野指針和內(nèi)存泄露問(wèn)題馍资。對(duì)象被莫名釋放筒主,那么就會(huì)崩潰。
注意:在MRC環(huán)境下使用retain修飾對(duì)象類型,使用assign實(shí)現(xiàn)基本類型.
在ARC環(huán)境下,strong相當(dāng)于retain,weak相當(dāng)于assign,
重點(diǎn)weak只能修飾對(duì)象鸟蟹,但是assign可以修飾對(duì)象和基本數(shù)據(jù)類型乌妙。
以上只是簡(jiǎn)單的理解。下面具體講一下建钥。一個(gè)對(duì)象可以有多個(gè)擁有者藤韵,只有我所有指向這個(gè)對(duì)象的指針全部銷毀。這個(gè)對(duì)象才會(huì)被釋放掉熊经。
strong指針的話很好理解泽艘。ARC環(huán)境下,默認(rèn)變量都是這種類型镐依。他會(huì)在創(chuàng)建和引用的時(shí)候都自動(dòng)計(jì)數(shù)器加一匹涮。然后只要有一個(gè)地方還引用著這個(gè)變量,系統(tǒng)就不會(huì)銷毀他槐壳。這里有一點(diǎn)需要講一下焕盟,如果strong類型的變量發(fā)生了值得改變,那么內(nèi)存地址也會(huì)隨之改變宏粤。 ?? 但是現(xiàn)在完全不需要考慮計(jì)數(shù)器了。不做過(guò)多解釋
weak的話灼卢,weak型的指針變量仍然可以指向一個(gè)對(duì)象绍哎,但不屬于對(duì)象的擁有.? 有點(diǎn)類似copy,但是又有不同鞋真。weak指針會(huì)在strong變量銷毀或者發(fā)生改變的時(shí)候把自己置為nil崇堰,避免野指針出現(xiàn)。
再深層次講解的話weak表其實(shí)是一個(gè)hash(哈希)表,Key是所指對(duì)象的地址海诲,Value是weak指針的地址(這個(gè)地址的值是所指對(duì)象的地址)數(shù)組繁莹。
截兩張圖看一下吧。PS:傳圖真麻煩特幔。
注意:self.seatDetail? 是weak類型W裳荨!少打印了一份地址蚯斯,當(dāng)他把值賦給weak的時(shí)候薄风,兩個(gè)weak公用一份地址。
很明顯可以看到拍嵌,我把一個(gè)strong變量賦值給weak遭赂,并沒(méi)有開(kāi)辟內(nèi)存空間。指向的是一份地址横辆,但是當(dāng)我blackBox發(fā)生改變的時(shí)候撇他,weak指向的還是舊的地址。不會(huì)跟隨改變狈蚤。接下來(lái)將一個(gè)新的weak賦值給weak
兩者會(huì)使用同樣的地址困肩。? 然后再賦值給strong的時(shí)候,strong的值和地址都會(huì)被改變?yōu)檫@個(gè)弱類型的炫惩。
重點(diǎn)在這里:按照之前各位大神說(shuō)的這個(gè)地址還是strong類型的僻弹。并不屬于weak,也就是說(shuō)如果strong銷毀他嚷。weak也會(huì)銷毀蹋绽。但是實(shí)際試驗(yàn)的結(jié)果卻是weak并沒(méi)有被置為nil,還是保留著那份內(nèi)存空間筋蓖。這就很費(fèi)解了卸耘。但是有一點(diǎn),他如果跟一個(gè)strong類型指向同一個(gè)對(duì)象粘咖。確實(shí)只會(huì)有一份內(nèi)存空間蚣抗。
那是不是可以理解為,weak依賴于strong瓮下,strong如果不存在翰铡,他才會(huì)持有這份地址。而且一旦strong再次被他賦值讽坏,地址就會(huì)重新回歸到strong锭魔。但是兩者同時(shí)都是weak的時(shí)候,依賴關(guān)系怎么算呢路呜?是否可以無(wú)數(shù)多個(gè)weak同時(shí)指向一份地址迷捧,然后銷毀一個(gè)其他的全部銷毀织咧?
下面講一下copy,其實(shí)copy跟strong的區(qū)別只在于setter方法的時(shí)候漠秋,copy會(huì)開(kāi)辟新的內(nèi)存笙蒙。strong不會(huì)。比如A(strong)庆锦,B(copy)捅位,C(對(duì)象)
C = @"000";//簡(jiǎn)單寫法,實(shí)際這是淺copy的寫法肥荔。其實(shí)覺(jué)得淺copy有點(diǎn)像weak绿渣,但是不能同論。
A = C;
B = C;
C = @"123";
NSLog:A = 123, B = 000, C = 123
結(jié)論:strong和weak值發(fā)生改變都會(huì)開(kāi)辟新的內(nèi)存空間燕耿,舊的對(duì)象如果有人引用中符,則不會(huì)被銷毀。如果無(wú)人引用誉帅。銷毀淀散。strong和copy具備持有能力。weak不具備蚜锨。? weak如果指向strong不會(huì)再持有档插,避免循環(huán)引用。weak指向weak亚再,一樣不會(huì)持有郭膛。weak指向copy,一樣不會(huì)持有氛悬。
提一下深淺copy吧则剃。深copy的目的就是希望幫助開(kāi)發(fā)者在使用復(fù)制出來(lái)的對(duì)象時(shí),能夠不影響原對(duì)象如捅。一般用于可變類型棍现。不可變類型就不要考慮什么深淺copy了。淺copy(指針copy)只是增加了一個(gè)指向原有對(duì)象的指針镜遣,并不開(kāi)辟內(nèi)存己肮。ARC下就是直接賦值。深copy則會(huì)開(kāi)辟一份新的內(nèi)存空間來(lái)管理兩個(gè)對(duì)象悲关。
然后自定義對(duì)象想要擁有拷貝功能谎僻,得自己遵循NSCopying協(xié)議,然后寓辱,復(fù)寫copyWithZone方法艘绍。
還有就是copy之后? 不管拿什么類型接收都會(huì)變成不可變類型,所以這時(shí)候調(diào)用可變類型的方法會(huì)崩潰? 只能調(diào)用不可變類型方法
mutableCopy之后都會(huì)變成可變類型讶舰。其他的同上
不管copy還是mutableCopy都是深copy,ARC環(huán)境下,系統(tǒng)幫大家省去了淺copy跳昼,直接賦值就是淺copy般甲。這個(gè)時(shí)候值會(huì)跟隨著變化。? 深copy則不會(huì)鹅颊。
更新:17.6.12
這里說(shuō)一下NSString屬性為什么要用copy屬性敷存,不是說(shuō)一定要用copy,包括我大部分時(shí)候是用的strong,但是如果這個(gè)string需要賦值給某個(gè)對(duì)象的屬性,就要注意了却嗡,修改原有string辕漂,對(duì)象的屬性也會(huì)隨之改變。如果用copy通砍,就會(huì)另開(kāi)辟內(nèi)存空間,不會(huì)強(qiáng)引用這個(gè)值。