你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> 搞定IPhone應用的內存洩露

搞定IPhone應用的內存洩露

編輯:IOS開發綜合

IPhone上木有垃圾回收,動態申請的內存要自己記得釋放,此文自己總結一下可能出現內存洩露的各種情況,以及檢測方法。
 
內存洩露說白了,就是有這樣一塊動態申請的內存,但木有任何一個指針指向它。
 
舉例來說,在C++中:
 
1. MyClass * foo = new MyClass; 
2. foo = NULL;
 
類似地在objective-C中:
 
1. MyClass *foo = [[MyClass alloc] init]; 
2. foo = nil;//內存洩露了!
 
 
或者有這樣一個類:
 
1. @interface Foo : NSObject 
2. {} 
3. @end 
4. 
5. @implementation Foo 
6. -(id) init 
7. { 
8.         if ((self = [super init])) { 
9.                 NSMutableString * string = [[NSMutableString alloc] initWithString:@"Leaker!!!"]; 
10.                 string = nil;//洩露了!這句之後那個字符串對象應用退出之前不會被釋放。
11.         } 
12.         return self; 
13. } 
14. - (void) dealloc 
15. { 
16.         [super dealloc]; 
17. } 
18. @end
 
出現內存洩露會怎樣?
答:很小的洩露,沒事!應用退出的時候所用內存都會被清理,包括洩露的,而且IPhone應用不會申請到共享內存,不會波及到整個系統,不會出現系統范圍的內存洩露。要是洩露的比較多,而且反復不停地出現內存洩露,頂多應用崩潰掉。不過想發布到AppStore的話,有內存洩露一般會被蘋果拒絕……。
 
先來看看IPhone裡內存是怎麼管理的,首先:木有自動垃圾回收!其次:有引用記數!
NSObject對象有個屬性:retainCount,所以所有對象都要繼承自NSObject,才有統一的引用計數…。
 
然後牢記記住下面8件事:
• 1 這個retainCount == 0的時候,對象的dealloc方法會被調用,對象就被釋放了。
• 2 永遠不要顯示調用dealloc方法
• 3 [obj retain]; // obj.retainCount++ 引用記數+1
• 4  [obj release]; // obj.retainCount-- 引用記數-1
• 5 MyClass * obj = [[MyClass alloc] init];// obj.retainCount = 1 初值為1
• 6 對於有retain特性的屬性比如下面這個:
1. @interface MyClass : NSObject { 
2.   NSObject* foo; 
3. } 
4. @property (noatomic,retain) NSObject * foo; 
5. @end 
6. 
7. @implementation MyClass 
8. @synthesize foo; 
9. ... 
10.   //下面兩行正確的寫法 
11.   self.foo = bar;// [foo release]; foo = bar; [foo retain]; 會發一個release給原來的對象,發一個retain 給新對象 
12.   self.foo = nil;// [foo release]; 會發一個release 消息給對象 
13. 
14.   //下面一行寫法不對 
15.   foo = bar;// 沒發release給foo 沒發retain給bar ,這種寫法是不對的。 
16. ... 
17. @end
  參考:
蘋果的文檔 和 具體實現的解釋

• 7 對於stringWithString 這種方法創造的對象,一個Runloop結束時,對象會被發送一個release消息,需要注意的有兩點,一是注意理解Runloop,避免Runloop結束後對象被釋放了卻又使用對象,二是 如果用instruments工具檢測內存洩露,這種使用autorelease的情況也會被當做內存洩露處理,注意識別……。
• 8 對於NSMutableArray這種類,當addObject的時候,相應被加入array中的那個對象的引用計數會被+1,當array本身釋放時,它會先給array中的所有對象發一個release消息。www.2cto.com
 
可以用Instruments檢測內存洩露,裡各種各樣的工具,用Leaks。
用起來很簡單:用Xcode(4.3)打開相應的項目,Product->Profile,選Leaks工具。 之後會動態地記錄應用運行過程中,有哪些地方出現內存洩露。 需要注意的地方有二:
1 對於被autorelease的對象,Leak工具也會視其為洩露,自己知道沒問題就行。
2 記得點開Extended Detail ,對於每一出洩露,可以在這裡看到調用堆棧,雙擊調用堆棧中的某一項,可以直接定位到代碼,便於查錯跟修改。 情況如下兩個圖:





作者:dawn110110

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved