1,什么是ARC, (Automatic Reference Counting)自動(dòng)引用計(jì)數(shù),是iOS5推出的內(nèi)存管理機(jī)制。
2,內(nèi)存管理原則
自己生成的對(duì)象自己持有。別人生成的對(duì)象自己也可以持有。不再需要自己持有的對(duì)象時(shí)釋放。 無(wú)法釋放非自己持有的對(duì)象。
3,引用計(jì)數(shù)
在iOS開發(fā)中的內(nèi)存管理規(guī)則,當(dāng)一個(gè)對(duì)象生成時(shí),其引用計(jì)數(shù)為1。當(dāng)其他屬性引用該對(duì)象時(shí),引用計(jì)數(shù)加1。當(dāng)該對(duì)象的引用計(jì)數(shù)大于0時(shí),該對(duì)象就不會(huì)被銷毀,當(dāng)持有對(duì)象的變量不需要持有時(shí)釋放該對(duì)象的引用, 引用計(jì)數(shù)減1。當(dāng)對(duì)象的引用計(jì)數(shù)為0時(shí),對(duì)象銷毀。這里面有幾個(gè)關(guān)鍵詞: 生成、持有、釋放、銷毀。
生成并持有對(duì)象 alloc/new/copy/mutableCopy等方法 引用計(jì)數(shù)為1
持有對(duì)象 retain方法 引用計(jì)數(shù) + 1
釋放對(duì)象 release方法 引用計(jì)數(shù) - 1
延時(shí)釋放對(duì)象 autorelease方法 當(dāng)自動(dòng)釋放池對(duì)象釋放的時(shí)候引用計(jì)數(shù)- 1
廢棄對(duì)象 dealloc方法 引用計(jì)數(shù)為0
手動(dòng)引用計(jì)數(shù)(MRC), 需要在編寫的時(shí)候顯示的調(diào)用內(nèi)存管理方法,由程序員自己管理內(nèi)存,這種方式有很大的弊端,過(guò)多的占用精力還有很大的出錯(cuò)的可能。
4,自動(dòng)引用計(jì)數(shù)
雖然內(nèi)存管理的原則都是利用引用計(jì)數(shù),但是自動(dòng)引用計(jì)數(shù)能夠利用編譯器特性在合適的位置自動(dòng)的插入內(nèi)存管理的代碼,這樣程序員就不用顯示的調(diào)用內(nèi)存管理相關(guān)的方法了,在一定程度上提高了效率。
自動(dòng)引用計(jì)數(shù)的原則:
不能再調(diào)用retain、retainCount、release、autorelease和dealloc方法
不能顯示的調(diào)用dealloc方法
不能調(diào)用autorelease方法,要換做使用@autorelease塊替代NSAutoreleasePool
5,變量的所有權(quán)修飾符
共四中__strong、__weak、__unsafe_unretained和__autoreleasing。
__strong修飾符
__strong修飾符是id類型和對(duì)象類型默認(rèn)的所有權(quán)修飾符。
__strong修飾符表示對(duì)對(duì)象的“強(qiáng)引用”。持有強(qiáng)引用的變量在超出其作用域時(shí)被廢棄,隨著強(qiáng)引用的失效,引用的對(duì)象會(huì)隨之釋放,引用計(jì)數(shù)減1。
__weak修飾符
__strong修飾符修飾的變量表示強(qiáng)引用,意味著只要還有一個(gè)強(qiáng)引用存在,對(duì)象就不可能釋放,但是有一個(gè)問(wèn)題就是兩個(gè)對(duì)象互相強(qiáng)引用,就會(huì)造成循環(huán)引用,__weak表示的是弱引用, 弱引用對(duì)對(duì)象的生命周期不會(huì)產(chǎn)生影響,并且當(dāng)對(duì)象銷毀時(shí),__weak修飾的變量會(huì)自動(dòng)設(shè)置為nil。所以可以用__weak修飾的變量是否為nil來(lái)判斷對(duì)象是否已經(jīng)被銷毀。
__unsafe_unretained
顧名思義,它是不安全的, 和__weak相似但是有區(qū)別,相同點(diǎn)就是不會(huì)對(duì)對(duì)象的生命周期產(chǎn)生影響, 不會(huì)影響對(duì)象的引用計(jì)數(shù),但是它是不安全的,當(dāng)對(duì)象被銷毀時(shí),它不會(huì)自動(dòng)設(shè)置為nil, 還是原來(lái)對(duì)象的地址。如果這個(gè)時(shí)候訪問(wèn)變量就會(huì)報(bào)野指針錯(cuò)誤,所以使用的時(shí)候一定要確保對(duì)象存在。
__autoreleasing
用__autoreleasing修飾的變量的作用等同于ARC無(wú)效時(shí)調(diào)用autorelease方法,都是起到延時(shí)釋放的作用。ARC有效時(shí),用@autoreleasepool塊替代NSAutoreleasePool類,用附有__autoreleasing修飾符的變量代替autorelease方法。
下面這些情況不用開發(fā)者顯示的指定__autoreleasing
1.對(duì)象作為函數(shù)的返回值,編譯器會(huì)自動(dòng)將其注冊(cè)到自動(dòng)釋放池。
//由于return使得對(duì)象變量超出其作用域,所以該強(qiáng)引用對(duì)應(yīng)的自己持有的對(duì)象會(huì)被自動(dòng)釋放,但該對(duì)象作為函數(shù)的返回值,編譯器會(huì)自動(dòng)將其注冊(cè)到autoreleasepool
2.id的指針或?qū)ο蟮闹羔樤跊](méi)有顯示指定時(shí)會(huì)被附加上__autoreleasing修飾符。
https://blog.csdn.net/junjun150013652/article/details/53149145