iphone 記憶體管理的一些總結

weixin_34262482發表於2011-02-10

   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'

  sent to dealloced instance 0xa4e10 of class NSConcreteData.

 

雖然也能大致判斷是哪種型別的變數重複釋放了,但資訊還不夠多,當專案大,原始碼比較多的時候,也不太方便定位,

在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掉。

 

    

 

相關文章