1、Objective-C內存管理簡介:
Objective-C需要自己考慮內存的管理,對於從Java, C#等語言轉向Objective-C平台的程序員新手來說,這是個很大的挑戰。幸運的是,如果熟悉了Objective-C的內存管理機制,手工管理內存也沒有那麼可怕。 Objective-C的內存管理介於C/C++和Java C#直接,不像C/C++語言內存管理全部需要程序員一手包辦,也不像Java C#語言有那麼完備的內存垃圾回收器。(Objective-C 2.0有GC機制,不過不支持IOS)。那他是怎麼管理內存的呢?通過引用計數進行管理的。PS:在iOS 5後增加了Automatic Reference Counting(ARC 自動引用計數)特性,這樣程序員不需要自己操心管理內存了,ARC和GC不一樣,ARC是編譯器的行為。ARC後面再講。不過熟悉Objective-C的內存管理機制是非常必要的。
2、內存管理原理:
Objective-C內存管理模型是基於對象的所有權。如果你擁有這個對象,那麼你就有責任去釋放它。一個對象可以有多個擁有者。如果這個對象的擁有和為0時,系統將自動釋放這個對象。對象的所有權和釋放有四個原則:
- 任何你創建的對象你都獲得其所有權。(包括 alloc ,new ,copy等關鍵字獲得的對象)
- 通過retain獲得對象的所有權
- 如果你不需要一個對象了,你必須釋放所有權
- 你不能釋放你沒有所有權的對象
引用計數(retainCount)是Objective-C對象引用的唯一依據。調用實例管理的release方法後,此屬性減1,減到為零時對象的dealloc方法被自動調用,進行內存回收操作,也就是說我們永不該手動調用對象的dealloc方法。
3、示例:環境是在不選擇ARC的環境下
新建Person類,使他繼承與NSObject,在.m文件中實現dealloc方法:
- - (void) dealloc
- {
- NSLog (@"dealloc called. Bye Bye.");
- [super dealloc];
-
- }
在引用計數為0時,這個方法就會被調用,證明這個對象被銷毀。
創建一個對象,打印它的引用計數
- Person *person = [[Person alloc] init];
-
- NSLog(@"對象person的retainCount: %d", [person retainCount]);
對象person的retainCount: 1
我們增加1
- Person *person = [[Person alloc] init];
- NSLog(@"對象person的retainCount: %d",[person retainCount] );
- [person retain];
- NSLog(@"對象person的retainCount: %d", [person retainCount]);
打印結果:
對象person的retainCount: 1
對象person的retainCount: 2
和傳說的一樣,retainCount增加了。可以有在release時,減少到1時就不再減 了
- Person *person = [[Person alloc] init];
- NSLog(@"對象person的retainCount: %d",[person retainCount] );
- [person retain];
- NSLog(@"對象person的retainCount: %d", [person retainCount]);
- [person release];
- [person release];
- NSLog(@"對象person的retainCount: %d", [person retainCount]);
這個代碼最後打印出來的retainCount是0嗎?打印結果:
- 2012-07-05 16:05:29.830 ObjectiveCTest[2847:f803] 對象person的retainCount: 1
- 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] 對象person的retainCount: 2
- 2012-07-05 16:05:29.831 ObjectiveCTest[2847:f803] dealloc called. Bye Bye.
- 2012-07-05 16:05:29.832 ObjectiveCTest[2847:f803] 對象person的retainCount: 1
震驚了,第一次release 時retainCount減1了,再release , d對象的dealloc called了,但是retainCount 還是1.在stackoverflow.com的查了一下,有人說這個retainCount沒什麼用。。。。可以事實的確如retainCount是1,對象被干掉了。有人說,要把person = nil。這樣retainCount就是0了。試了下,nil的 retainlCount永遠是0.這個賦值沒有意義。