第五章 基於引用計數的內存管理
1.內存管理必要性
ARC是Mac OS X 10.7和iOS 5引入的新特性,也是蘋果公司推薦是用的內存管理方法。啟用ARC後,編譯器會在適當的地方自動加入retain,release,autorelease等語句,來簡化objective-C編程在內存管理方面的工作量。
程序未能釋放已經不再是用的內存叫做內存洩露(memory leak)。
如果訪問了已經被釋放的內存,則會造成數據錯誤,嚴重時導致程序異常終止,在指針所指向的對象已被釋放或回收的情況下,該指針就稱為野指針(懸垂指針),繼續是用這種指針會造成程序崩潰。
2.自用技術,自動引用計數和自動垃圾回收
Cocoa環境的objective-C提供了一種動態的內存管理方式,稱為引用計數(reference counter)。這種方式會跟蹤每個對象被引用的次數,當對象的引用次數為0時,系統就會釋放這個對象所占用的內存,稱為基於引用計數的內存管理。
手動引用計數(MRC) 自動引用計數(ARC)另外在MAC開發中還支持垃圾回收來管理內存。(垃圾回收第六章詳解)
釋放內存的並不是release,而是dealloc方法,同alloc不同,dealloc不是類方法而是一個勢力方法。沒收到一個release消息,對象的引用計數值就會減一。當對象的引用計數值是0的時候,系統就知道這個對象不再需要了。OC會自動向對象發送條dealloc消息來釋放內存。通常不允許直接調用dealloc方法。。
3.自動釋放
cocoa環境的OC提供一種對象自動釋放(autorelease)的機制。這種機制的基本思想是把所有需要發送release消息的對象都記錄下來。等到需要釋放這些對象時,會給這些對象一直發送release消息。類NSautoreleasePoo(自動釋放池 )就起到了記錄的作用。
4.臨時對象的生成
OC的很多類都提供一種生成臨時對象的方法,這種類方法的命名規則是不以init開頭,而以要生成的對象的類型作為開頭,例如stringWithFormat:,這種方法稱為遍歷構造函數。這種臨時對象生成後會被直接加入到內部的自動釋放池,你不需要關心如何銷毀它,區別於alloc,init創建的對象。
5.運行回路RunLoop
6.單例對象的簡單創建(不考慮多線程安全,繼承)
+(MyComponent)sharedMyComponent{
static MyConponent * shared;
if(shared == nil){
shared = [MyConponent alloc] init];
return shared;
}
}
7.什麼是ARC
ARC(Automatic Reference Counting 自動引用計數)是一個編譯器計數,利用此計數可以簡化OC在內存管理方面的工作量。編譯器會根據賦值操作,變量的初始化,變量的生命周期等因素,在核實的位置自動加入保持和釋放(retain/release)相關的代碼,至於在神峨眉位置加入什麼樣的代碼,編譯器會自己判斷。
8.利用ARC時程序員需要遵守的規則和一些新增的概念和語法
禁止調用引用計數的相關函數 例如retain ,release,autorelease,retainCount
管理自動釋放池的新語法
ARC中禁止使用NSAutoReleasePool,而是使用新語法@autoreleasepool來管理自動釋放池。
手動管理內存情況下,自動釋放池這樣寫
id pool = [NSAutoreleasePool alloc] init];
/ * 進行一系列操作 */
/ * 此處不可以使用break,return,goto之類的語句 * /
[pool release]; /* 釋放對象*/
新的語法如下所示:
@autoreleasepool{
/ *在此進行一系列操作*/
/ * 可以使用break,return,goto等語句 */
}
@autoreleasepool在非ARC模式下也能使用,並且使用@autoreleasepool比使用第一種性能更好效率更高,所以無論是否是ARC,都推薦用第二種新語法。
9.變量的初始值
在ARC中,未指定初始值的變量(包括局部變量)都會被初始化為nil。
但是對於用_autoreleaseing 和_unsafe_unretained 修飾的變量來說,初始值是未定的。而對象以為的變量的初值和以前是一樣的。
10.方法族
同對象申生成相關的方法集合叫做方法族(method family)
目前一共定義了5個方法族 alloc方法族,copy方法族,mutableCopy方法族,new方法族,init方法族。
11.方法dealloc的定義
手動管理內存情況下,當變量的引用計數為0的時候dealloc就會被調用並釋放內存。所以,實例對象被釋放前的所有“善後操作”都被定義在了dealloc中。
在ARC時,當對象被釋放的時候,對象dealloc函數也會被調用,但又一些需要注意的地方:
首先:要被釋放的對象的實例變量被另外一個對象保持的情況下,SRC會自動進行釋放,因此不需要做任何處理(手動管理內存時,需要執行release操作讓變量的引用計數減1)
其次:不能顯示的調用dealloc。ARC的時候也不能調用父類的dealloc,盡管你可以創建一個定制的dealloc方法來釋放資源而不是實例變量,單頁不要調用【super dealloc】因為編譯器會自動處理這些事情,如果你在代碼調用了【super dealloc】會編譯出錯error:ARC forbids explicit messagesendof“dealloc”