ARC全稱為Automatic Reference Counting禾进,也就是編譯器為我們自動添加retain/release/autorelease等語句豁跑,保證引用計(jì)數(shù)的正確性,而不需要我們自己添加泻云,僅僅如此艇拍。ARC不代表像Java那樣有GC做垃圾回收狐蜕,所以本質(zhì)上還是要“手動”管理內(nèi)存的。
而@autoreleasepool 可以幫助我們自動回收內(nèi)存卸夕。當(dāng)@autoreleasepool結(jié)束的時候层释,被ARC自動標(biāo)記過autorelease的對象都會被release掉,也就是會被釋放掉快集。
有些人會有些疑問贡羔,不管是在MRC還是ARC環(huán)境下,對象retain count為0的時候个初,對象都會被釋放乖寒,為什么我們還要使用@autoreleasepool呢,不是多此一舉嗎院溺?正常情況下楣嘁,一個被標(biāo)記為“autorelease”的對象,在retain count為0的時候覆获,要等到當(dāng)前runloop結(jié)束的時候瓢省,才會被釋放。而在當(dāng)前runloop結(jié)束之前勤婚,可能會出現(xiàn)無數(shù)個等待被釋放而沒有被釋放的對象,這時候內(nèi)存占用率就會比較高缨称。恰當(dāng)?shù)氖褂聾autoreleasepool可以及時釋放這些對象祝迂,降低內(nèi)存的使用率。
根據(jù)Apple的文檔当凡,@autoreleasepool使用場景如下:
- 寫基于命令行的的程序時沿量,就是沒有UI框架冤荆,如AppKit等Cocoa框架時。
- 寫循環(huán)乌妒,循環(huán)里面包含了大量臨時創(chuàng)建的對象。(本文的例子)
- 創(chuàng)建了新的線程撤蚊。(非Cocoa程序創(chuàng)建線程時才需要)
- 長時間在后臺運(yùn)行的任務(wù)。
對于每一個Runloop(或者稱為事件周期)冗茸, 系統(tǒng)會隱式創(chuàng)建一個Autorelease pool(自然會有多個Autorelease pool)匹中,這樣所有的release pool會構(gòu)成一個象CallStack一樣的一個棧式結(jié)構(gòu),在每一個Runloop結(jié)束時挂绰,當(dāng)前棧頂?shù)腁utorelease pool會被銷毀服赎,這樣這個pool里的每個Object會被release。那什么是一個Runloop呢践付? 一個UI事件缺厉,Timer call, delegate call命爬, 都會是一個新的Runloop辐脖。