如果要說iOS的內(nèi)存管理問題浑玛,先要知道Objective-C是一門什么樣的語言 —> Objective-C是一門面向?qū)ο蟮恼Z言挑秉。
我們知道在程序運行過程中要創(chuàng)建大量的對象舅逸,和其他高級語言類似粹淋,在Objective-C中對象時存儲在堆中的,系統(tǒng)并不會自動釋放堆中的內(nèi)存(注意基本類型是由系統(tǒng)自己管理的桶错,放在棧上入:int float 等)。如果一個對象創(chuàng)建并使用后沒有得到及時釋放那么就會占用大量內(nèi)存胀蛮。其他高級語言如C#院刁、Java都是通過垃圾回收來(GC)解決這個問題的,但在Objective-C中并沒有類似的垃圾回收機制粪狼,因此它的內(nèi)存管理就需要由開發(fā)人員手動維護退腥。今天將著重介紹Objective-C內(nèi)存管理:
一、Objective-C 內(nèi)存管理的對象
1再榄、內(nèi)存管理的對象主要有兩類:
①基本數(shù)據(jù)類型:int 狡刘、float、 struct 等困鸥。
②引用類型:繼承自NSObject類的所有Objective-C對象嗅蔬。
第一種基本數(shù)據(jù)類型不需要我們管理,第二種需要管理疾就。2澜术、管理內(nèi)存的原理:
①值類型一般都會被放入棧中(先進后出),引用類型會被放到堆中猬腰,當(dāng)給對象分配內(nèi)存空間時鸟废,會隨機從內(nèi)存當(dāng)中開辟空間,對象和對象之間可能會存在很多碎片姑荷,這些碎片空間需要我們管理盒延。
②棧內(nèi)存從性能上來說優(yōu)于堆內(nèi)存,數(shù)據(jù)量過大的時候鼠冕,我們會把數(shù)據(jù)存入堆中添寺,然后在棧中存放堆的地址,這樣調(diào)用數(shù)據(jù)的時候供鸠,就可以快速的通過棧中的地址拿到堆中的數(shù)據(jù)畦贸。
③裝箱:把int等包裝成NSNumber(會降低性能);
拆箱:把NSNumber轉(zhuǎn)化為float等 (注意類型錯誤時候的安全性問題)楞捂;
裝箱和拆箱會增加代碼的運行時間薄坏,降低代碼可讀性,影響性能寨闹。
二胶坠、內(nèi)存管理方式 主要是MRC和ARC管理方式;
- MRC:手動管理內(nèi)存有時候并不容易繁堡,因為對象的引用有時候是錯綜復(fù)雜的沈善,對象之間可能互相交叉引用乡数,此時需要遵循一個法則:誰創(chuàng)建,誰釋放闻牡。
- ARC:在Objective-C中也有一種內(nèi)存自動釋放的機制叫做“自動引用計數(shù)”(或“自動釋放池”)净赴,與C#、Java不同的是罩润,這只是一種半自動的機制玖翅,有些操作還是需要我們手動設(shè)置的。自動內(nèi)存釋放使用@autoreleasepool關(guān)鍵字聲明一個代碼塊割以,如果一個對象在初始化時調(diào)用了autorelase方法金度,那么當(dāng)代碼塊執(zhí)行完之后,在塊中調(diào)用過autorelease方法的對象都會自動調(diào)用一次release方法严沥。這樣一來就起到了自動釋放的作用猜极,同時對象的銷毀過程也得到了延遲(統(tǒng)一調(diào)用release方法)。
autorelease方法不會改變對象的引用計數(shù)器消玄,只是將這個對象放到自動釋放池中跟伏;
自動釋放池實質(zhì)是當(dāng)自動釋放池銷毀后調(diào)用對象的release方法,不一定就能銷毀對象(例如如果一個對象的引用計數(shù)器>1則此時就無法銷毀)莱找;
由于自動釋放池最后統(tǒng)一銷毀對象酬姆,因此如果一個操作比較占用內(nèi)存(對象比較多或者對象占用資源比較多),最好不要放到自動釋放池或者考慮放到多個自動釋放池奥溺;
ObjC中類庫中的靜態(tài)方法一般都不需要手動釋放,內(nèi)部已經(jīng)調(diào)用了autorelease方法骨宠;
三浮定、MRC與ARC混編 在ARC項目中,對MRC文件可以添加 -fno-objc-arc標(biāo)識层亿;在MRC中桦卒,對ARC的文件可以添加 -fobjc-arc 的標(biāo)識。(或者可以把MRC文件轉(zhuǎn)為ARC匿又,現(xiàn)在多用ARC方灾,但是有些第三方框架還是MRC的需要處理);