如何使用內(nèi)存以及如何分配內(nèi)存對于設(shè)備和用戶體驗至關(guān)重要。OC語言作為C語言的超集,對于內(nèi)存以及內(nèi)存管理方面非常重要。從Xcode 4.2之后蘋果公司采用了ARC編譯器特性的內(nèi)存管理機制,大大的減少了程序員手動對內(nèi)存的管理。
OC的內(nèi)存管理一般是對OC對象進行管理,包括任何繼承了NSObject的對象,因為OC對象是存放于堆中,而非OC對象一般放在棧里面,會被系統(tǒng)自動回收。
MRC
1.引用計數(shù)器
(1)引用計數(shù)器表示有多少人正在使用這個對象。
(2)當沒有任何人使用這個對象時, 系統(tǒng)才會回收這個對象, 也就是說當對象的引用計數(shù)器為0時,對象 占用的內(nèi)存就會被系統(tǒng)回收。
(3)如果對象的計數(shù)器不為0,那么在整個程序運行過程,它占用的內(nèi)存就不可能被回收(除非整個程序 已經(jīng)退出 )
(4)任何一個對象, 剛生下來的時候, 引用計數(shù)器都為1
(5)當使用alloc、new或者copy(MutableCopy)創(chuàng)建一個對象時,對象的引用計數(shù)器默認就是1
2.引用計數(shù)器的操作
(1)給對象發(fā)送一條retain消息,可以使引用計數(shù)器值+1(retain方法返回對象本身)
(2)給對象發(fā)送一條release消息, 可以使引用計數(shù)器值-1
(3)給對象發(fā)送retainCount消息, 可以獲得當前的引用計數(shù)器值(retainCount有時候會不準確, 建議采用delloc方法來驗證是否完全內(nèi)存釋放)
注意: release并不代表銷毀\回收對象, 僅僅是計數(shù)器-1
3.dealloc方法
(1)當一個對象的引用計數(shù)器值為0時,這個對象即將被銷毀,其占用的內(nèi)存被系統(tǒng)回收。
(2)對象即將被銷毀時系統(tǒng)會自動給對象發(fā)送一條dealloc消息 (因此, 從dealloc方法有沒有被調(diào) 用,就可以判斷出對象是否被銷毀)
dealloc方法的重寫 一般會重寫dealloc方法,在這里釋放相關(guān)資源,dealloc就是對象的遺言
總之就是
(1)誰創(chuàng)建誰release :
如果你通過alloc、new或[mutable]copy來創(chuàng)建一個對象,那么你必須調(diào)用release或 autorelease
誰retain誰release: (2)只要你調(diào)用了retain,就必須調(diào)用一次release
ARC
自動引用計數(shù),解決了iOS開發(fā)者的內(nèi)存管理的麻煩。
1.ARC機制判斷注意點及優(yōu)點 ARC機制判斷,ARC機制下有幾個明顯的標志: 不允許調(diào)用對象的release方法 再重寫父類的dealloc方法時,不能再調(diào)用 [super dealloc];
優(yōu)點
ARC是編譯器特性,而不是運行時特性 ARC不是其它語言中的垃圾回收,有著本質(zhì)區(qū)別,ARC完全消除了手動管理內(nèi)存的煩瑣,基本上能夠避免內(nèi)存泄露有時還能更加快速,因為編譯器還可以執(zhí)行某些優(yōu)化。
2.強指針,弱指針
強指針
默認所有指針變量都是強指針 被__strong修飾的指針
弱指針
被__weak修飾的指針
3.ARC下單對象內(nèi)存管理 (1)局部變量釋放對象隨之被釋放 (2)清空指針對象隨之被釋放 (3)默認清空所有指針都是強指針 弱指針需要明確說明 。注意: 千萬不要使用弱指針保存新創(chuàng)建的對象。
4.ARC下循環(huán)引用問題
與MRC一樣,當兩個對象相互引用時,會出現(xiàn)內(nèi)存泄露的問題,解決辦法是:一個用strong一個用 weak。
5.ARC下@property參數(shù)
strong: 用于OC對象, 相當于MRC中的retain
weak: 用于OC對象, 相當于MRC中的assign
assign: 用于基本數(shù)據(jù)類型, 跟MRC中的assign一樣(默認值)
另外概念
1.堆棧,其中棧是由系統(tǒng)自動分配釋放,存放函數(shù)的參數(shù)值,局部變量等;而堆是由程序員釋放,若程序員不釋放,程序結(jié)束時可能由系統(tǒng)回收。
2.僵尸對象
已經(jīng)被銷毀的對象(不能再使用的對象)
3.野指針
指向僵尸對象(不可用內(nèi)存)的指針 給野指針發(fā)消息會報EXC_BAD_ACCESS錯誤
4.空指針
沒有指向存儲空間的指針(里面存的是nil, 也就是0) 給空指針發(fā)消息是沒有任何反應(yīng)的 為了避免野指針錯誤的常?辦法
在對象被銷毀之后, 將指向?qū)ο蟮闹羔樧優(yōu)榭罩羔?br>
5.@property參數(shù)
(1)控制set方法的內(nèi)存管理
retain : release舊值,retain新值(用于OC對象)
assign : 直接賦值,不做任何內(nèi)存管理(默認,用于非OC對象類型) copy : release舊值,copy新值(一般用于NSString *)
(2)控制需不需要生成set方法
readwrite :同時生成set方法和get方法(默認)
readonly :只會生成get方法
(3)多線程管理
atomic :性能低(默認)
nonatomic :性能高(iOS開發(fā)中都用這個屬性)
(4)控制set方法和get方法的名稱
setter : 設(shè)置set方法的名稱,一定有個冒號:
getter : 設(shè)置get方法的名稱 若有bool類型時最好修改getter方法為:(getter = isXXX) 注意: 不同類型的參數(shù)可以組合在一起使用
(5)循環(huán)引用 當使用@property屬性聲明兩個對象時,如果同時使用retain,會到時相互引用,內(nèi)存不會釋放,解決辦法是,一個用retain,一個用assign。