? ? ? OC采用了引用計(jì)數(shù)(retain count)對(duì)對(duì)象內(nèi)存進(jìn)行管理,例如,某個(gè)對(duì)象alloc了,那么這個(gè)對(duì)象的引用計(jì)數(shù)就加1,retain時(shí)加1,當(dāng)對(duì)象不需要用時(shí)就需要銷毀對(duì)象,釋放內(nèi)存,需要對(duì)象調(diào)用release方法,release會(huì)讓引用計(jì)數(shù)減1,只有引用計(jì)數(shù)消失,相當(dāng)于等于0,對(duì)象才會(huì)調(diào)用dealloc真正銷毀這個(gè)對(duì)象。
? ? ?每個(gè)OC對(duì)象都有自己的引用計(jì)數(shù)器,是一個(gè)整數(shù)表示對(duì)象被引用的次數(shù)钩骇,即現(xiàn)在有多少東西在使用這個(gè)對(duì)象。對(duì)象剛被創(chuàng)建時(shí)边琉,默認(rèn)計(jì)數(shù)器值為1,當(dāng)計(jì)數(shù)器的值變?yōu)?時(shí)记劝,則對(duì)象銷毀变姨。
ARC是xcode5中引入的自動(dòng)引用計(jì)數(shù),其原理與MRC是一樣厌丑,只是系統(tǒng)幫助我們添加了retain和release定欧。
蘋果官方對(duì)于ARC機(jī)制中對(duì)象的內(nèi)存引用規(guī)則:
(1)任何對(duì)象,如果仍有持有者怒竿,就不會(huì)銷毀
(2)任何對(duì)象砍鸠,已經(jīng)沒有任何持有者,即自動(dòng)銷毀
持有者就是指向?qū)ο蟮闹羔樃郏绻莝trong修飾的爷辱,即是對(duì)象的持有者,如果是weak屬性的,則不是持有者
? ? ?現(xiàn)實(shí)中的許多舊的項(xiàng)目饭弓,還有一些比較老的第三方庫(kù)双饥,可能都是采用MRC環(huán)境編寫的,我們?cè)趯?duì)其進(jìn)行擴(kuò)展或者做新項(xiàng)目的兼容的時(shí)候弟断,可以在xcode中對(duì)其進(jìn)行混編咏花。
選擇:target->build phases->compile sources
如果工程是ARC,要混編MRC的文件夫嗓,我們選中compiler flags迟螺,后面設(shè)置為-fno-objc-arc
如果工程是MRC冲秽,要混編ARC文件舍咖,我們?cè)诤竺嬖O(shè)置-fobjc-arc
MRC模式下,所有的對(duì)象都需要手動(dòng)的添加retain锉桑、release代碼來管理內(nèi)存排霉,必須遵守誰創(chuàng)建,誰回收的原則民轴。引用計(jì)數(shù)為0的時(shí)候攻柠,必須回收,如果沒有回收后裸,會(huì)造成內(nèi)存泄露瑰钮,如果繼續(xù)釋放,會(huì)造成野指針微驶。引用計(jì)數(shù)不為0浪谴,不能回收。release后的對(duì)象因苹,雖然已經(jīng)釋放苟耻,但是它的指針地址仍然存在,只是指向了一塊已經(jīng)釋放且無用的內(nèi)存扶檐,所以我們建議release后直接賦個(gè)nil來置空凶杖。
ARC(自動(dòng)引用計(jì)數(shù)),可以自動(dòng)的管理內(nèi)存款筑。在ARC模式下智蝠,只要沒有強(qiáng)指針(強(qiáng)引用)指向?qū)ο螅瑢?duì)象就會(huì)被釋放奈梳。在ARC模式下杈湾,不允許使用retain、release颈嚼、retainCount等方法毛秘。并且,如果使用dealloc方法時(shí),不允許調(diào)用[super dealloc]方法叫挟。ARC**模式下的property變量修飾詞為strong艰匙、weak,相當(dāng)于MRC模式下的retain抹恳、assign员凝。strong :代替retain,缺省關(guān)鍵詞奋献,代表強(qiáng)引用健霹。weak:代替assign,聲明了一個(gè)可以自動(dòng)設(shè)置nil的弱引用瓶蚂,但是比assign多一個(gè)功能糖埋,指針指向的地址被釋放之后,指針本身也會(huì)自動(dòng)被釋放窃这。
ARC機(jī)制的使用規(guī)則
(1)不能使用NSAllocateObjec或NSDeallocateObject函數(shù)來創(chuàng)建對(duì)象
(2)不能在C語言的結(jié)構(gòu)體中使用對(duì)象指針瞳别,同時(shí)建議用object-c的類來管理數(shù)據(jù)而不是結(jié)構(gòu)體
(3)不得使用NSAutoreleasePool對(duì)象。ARC中杭攻,全部使用@autorelease關(guān)鍵字代替祟敛,且比NSAutoreleasePool更高效
(4)不得使用內(nèi)存Zone,那些牽涉NSZone的方法都不得使用。
(5)不得對(duì)一個(gè)屬性變量的取值方法命名以new開頭
(6)outlet均用weak關(guān)鍵字修飾兆解,除非他是xib中最頂部的界面元素馆铁,則需要strong。
(7)Core Foundation不適合ARC锅睛,該創(chuàng)建的仍創(chuàng)建埠巨,該釋放的仍釋放。
其中關(guān)于自動(dòng)釋放池:
? ? ?當(dāng)向一個(gè)對(duì)象發(fā)送一個(gè)autorelease消息時(shí),Cocoa就會(huì)將該對(duì)象的一個(gè)引用放入到最新的自動(dòng)釋放池衣撬。它仍然是個(gè)正當(dāng)?shù)膶?duì)象,因此自動(dòng)釋放池定義的作用域內(nèi)的其它對(duì)象可以向它發(fā)送消息乖订。當(dāng)程序執(zhí)行到作用域結(jié)束的位置時(shí),自動(dòng)釋放池就會(huì)被釋放,池中的所有對(duì)象也就被釋放。
? ? ?Objective-C是通過一種"referring counting"(引用計(jì)數(shù))的方式來管理內(nèi)存的, 對(duì)象在開始分配內(nèi)存(alloc)的時(shí)候引用計(jì)數(shù)為一,以后每當(dāng)碰到有copy,retain的時(shí)候引用計(jì)數(shù)都會(huì)加一, 每當(dāng)碰到release和autorelease的時(shí)候引用計(jì)數(shù)就會(huì)減一,如果此對(duì)象的計(jì)數(shù)變?yōu)榱?, 就會(huì)被系統(tǒng)銷毀.
? ? ?NSAutoreleasePool(MRC)和@autorelease(ARC)就是用來做引用計(jì)數(shù)的管理工作的,這個(gè)東西一般不用你管的. autorelease和release沒什么區(qū)別,只是引用計(jì)數(shù)減一的時(shí)機(jī)不同而已,autorelease會(huì)在對(duì)象的使用真正結(jié)束的時(shí)候才做引用計(jì)數(shù)減一具练。