iphone 裡採用Object c 開發,相對來說,只要遵循了apple的一些程式設計規則,比C++的記憶體管理來的容易些,但是也有很多需要注意的地方,一旦出現記憶體相關的錯誤,除錯也是個很頭疼的問題。
1. 比如出現 EXC_BAD_ACCESS 錯誤,給你的錯誤提示就這個,如何根本沒法知道哪裡錯誤了,其實還是有方法知道的,
做如下設定:
Project -> Edit active executable ->Argument
新增如下四個引數
NSDebugEnabled
NSZombieEnabled
MallocStackLogging
MallocStackLoggingNoCompact
並都設定為YES。具體如下圖:
這個時候,如果有如下一段程式碼:
//重複釋放一個變數
NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
NSData* data = [NSData dataWithBytes:"asklaskdxjgr" length:12];
[data release];
[pool release];
再Debug視窗會有如下的提示
2003-03-18 13:01:38.644 autoreleasebug[3939] *** *** Selector 'release'
雖然也能大致判斷是哪種型別的變數重複釋放了,但資訊還不夠多,當專案大,原始碼比較多的時候,也不太方便定位,
在console視窗執行如下命令可以得到更多資訊:shell malloc_history <pid> <address>"
輸入命令:shell malloc_history 3939 0xa4e10
就會出現更多的資訊:
[dave@host193 Frameworks]$ malloc_history 3939 0xa4e10
Call [2] [arg=32]: thread_a0000dec |0x1000 | start | _start | main |
+[NSData dataWithBytes:length:] | NSAllocateObject | object_getIndexedIvars |
malloc_zone_calloc
這個時候就知道具體哪個函式出先問題了,從這裡可以看到main裡NSData出現問題了。
2. NSArray等集合類的實用問題。
如下面的程式碼
ReleaseTest* rt = [[alloc] init];
NSMutableArray *array = [[NSMutableArray alloc] init] ;
[array addObject: rt];
ReleaseTest *rt2 = [array objectAtIndex:0];
[rt2 release];
[array release];
[rt release];
就會導致重複釋放記憶體問題,因為rt2,獲取的是一個物件的指標,如果已經釋放了的話,rt在釋放的話,就重複了,為了遵循誰Init誰Release的原則,rt2就不應該Release。
3. init 和 Release 的問題。
凡是物件通過Init的方法生成的物件,都需要自己負責Release。
凡不是通過Init的方法生成的物件,不需要負責Release.如[NSString StringWithFormat]方法生成的物件就不需要自己Release,因此自己定義函式,返回一個類的時候,一定要設定為autoRelease 。這樣呼叫的人就不用操心是否需要釋放物件了。
4. AutoReleasePool裡最好不要將AutoRelease物件賦值給其它物件,否則離開這個作用域後,物件將會Release掉。