Objective-C如何對內(nèi)存管理的?

Objective-C的內(nèi)存管理主要有三種方式ARC(自動內(nèi)存計數(shù))、手動內(nèi)存計數(shù)、內(nèi)存池。

  • (Garbage Collection)自動內(nèi)存計數(shù):這種方式和Java類似,在你的程序的執(zhí)行過程中。始終有一個高人在背后準(zhǔn)確地幫你收拾垃圾,你不用考慮它什么時候開始工作,怎樣工作。你只需要明白,我申請了一段內(nèi)存空間,當(dāng)我不再使用從而這段內(nèi)存成為垃圾的時候,我就徹底的把它忘記掉,反正那個高人會幫我收拾垃圾。遺憾的是,那個高人需要消耗一定的資源,在攜帶設(shè)備里面,資源是緊俏商品所以iPhone不支持這個功能。所以“Garbage Collection”不是本入門指南的范圍,對“Garbage Collection”內(nèi)部機(jī)制感興趣的同學(xué)可以參考一些其他的資料,不過說老實(shí)話“Garbage Collection”不大適合適初學(xué)者研究。
    解決: 通過alloc – initial方式創(chuàng)建的, 創(chuàng)建后引用計數(shù)+1, 此后每retain一次引用計數(shù)+1, 那么在程序中做相應(yīng)次數(shù)的release就好了.
  • (Reference Counted)手動內(nèi)存計數(shù):就是說,從一段內(nèi)存被申請之后,就存在一個變量用于保存這段內(nèi)存被使用的次數(shù),我們暫時把它稱為計數(shù)器,當(dāng)計數(shù)器變?yōu)?的時候,那么就是釋放這段內(nèi)存的時候。比如說,當(dāng)在程序A里面一段內(nèi)存被成功申請完成之后,那么這個計數(shù)器就從0變成1(我們把這個過程叫做alloc),然后程序B也需要使用這個內(nèi)存,那么計數(shù)器就從1變成了2(我們把這個過程叫做retain)。緊接著程序A不再需要這段內(nèi)存了,那么程序A就把這個計數(shù)器減1(我們把這個過程叫做release);程序B也不再需要這段內(nèi)存的時候,那么也把計數(shù)器減1(這個過程還是release)。當(dāng)系統(tǒng)(也就是Foundation)發(fā)現(xiàn)這個計數(shù)器變 成員了0,那么就會調(diào)用內(nèi)存回收程序把這段內(nèi)存回收(我們把這個過程叫做dealloc)。順便提一句,如果沒有Foundation,那么維護(hù)計數(shù)器,釋放內(nèi)存等等工作需要你手工來完成。
    解決:一般是由類的靜態(tài)方法創(chuàng)建的, 函數(shù)名中不會出現(xiàn)alloc或init字樣, 如[NSString string]和[NSArray arrayWithObject:], 創(chuàng)建后引用計數(shù)+0, 在函數(shù)出棧后釋放, 即相當(dāng)于一個棧上的局部變量. 當(dāng)然也可以通過retain延長對象的生存期.
  • (NSAutoRealeasePool)內(nèi)存池:可以通過創(chuàng)建和釋放內(nèi)存池控制內(nèi)存申請和回收的時機(jī).
    解決:是由autorelease加入系統(tǒng)內(nèi)存池, 內(nèi)存池是可以嵌套的, 每個內(nèi)存池都需要有一個創(chuàng)建釋放對, 就像main函數(shù)中寫的一樣. 使用也很簡單, 比如[[[NSString alloc]initialWithFormat:@”Hey you!”] autorelease], 即將一個NSString對象加入到最內(nèi)層的系統(tǒng)內(nèi)存池, 當(dāng)我們釋放這個內(nèi)存池時, 其中的對象都會被釋放

第三方內(nèi)存泄漏檢測工具:MLeaksFinder原理分析

MLeakFinder的UIViewController擴(kuò)展在load方法中,viewDidDisappear:的實(shí)現(xiàn)配合 UINavigationController來在UIViewController被pop出去的時候調(diào)用willDealloc。
willDealloc 的實(shí)現(xiàn)首先調(diào)用了 NSObject+MemoryLeak 擴(kuò)展的 willDealloc,
willDealloc 然后調(diào)用 willReleaseChildren 構(gòu)建了parentPtrs用來判斷父對象是否被釋放,還有viewStack來展示層級結(jié)構(gòu)。
willDealloc的NSObject默認(rèn)實(shí)現(xiàn)在兩秒后,如果沒有被釋放,就調(diào)用assertNotDealloc。(父對象會比子對象的生命周期先結(jié)束)
assertNotDealloc 先判斷是否有父對象未釋放

  • 如果沒有就使用當(dāng)前對象
  • 創(chuàng)建MLeakedObjectProxy關(guān)聯(lián)到當(dāng)前對象
  • 將當(dāng)前對象指針加入到leakedObjectPtrs
  • 當(dāng)前對象被釋放的時候?qū)?yīng)的MLeakedObjectProxy會被釋放
  • MLeakedObjectProxy被釋放的時候,對應(yīng)的對象被從leakedObjectPtrs移除
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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