[Objective-C]記憶體流失是新手必然要經曆的痛,NSMutableArray的正確使用

來源:互聯網
上載者:User

Objective-C程式開發中的記憶體流失問題是新手非常頭痛的事情,可能是用C#這類自動垃圾釋放的語言太習慣了,用xcode中的profile工具查了一下我寫的小程式,記憶體流失了一大堆,經過一陣子排查,在NSMutableArray中添加對象後不正確維護對象的引用計數是一個主要原因。

在NSMutableArray how to properly addObjects and release這個討論主題中,給出了正確的使用NSMutableArray的步驟,先看他給出的代碼。

NSMutableArray *listData = [[NSMutableArray alloc] init];

for (int i = 0; i < 3; i++) { 
    MyData *obj = [[MyData alloc] init];
    NSString *name = nil;  
    switch (i)     {
        case 0:   
           name = @"Semen";   
           break;    
       case 1:         
           name = @"Ivan"; 
           break;           
       case 2:        
           name = @"Stepan";  
           break;         
       default:       
           break;  
    }         
    obj.name = name;   
    [listData addObject: obj];  
   [obj release];


[listData release];   裡面提到了3個問題,翻譯後加上我的理解:

(1)NSMutableArray這個數組裡麵包含的對象是什嗎?是對象的一份拷貝,還只是一個對象的指標?

答:數組裡存放的不是對象的複本,只是對象的指標。

按以前所學的C++的思維方式,上面的這句[obj release]是最難理解的,我把obj放在數組裡,數組裡存放的是對象的引用,為什麼把obj釋放了?這樣數組裡存放了一個無效的指標?實際上還是思維方式沒有轉變過來,在Objective-C中,[obj release]只表示obj收到一個release訊息,如果它的引用計數沒有變成0,它就不會釋放,而在C++中見到這個release就想到了釋放。我們來看一個過程:

MyData *obj = [[MyData alloc] init];   //obj用了init方法,按照約定,obj的引用計數是1,並且要自已來維護釋放過程

[listData addObject: obj];    //obj在放到數組裡的時候會自動給obj的引用計數加1,這時obj的引用計數就是2

[obj release];  //為了維持obj的正常計數值,用這條語句讓obj的引用計數為1,僅此而已,並沒有被釋放掉!

[listData release]; // 這句會給obj再發一個release訊息,這樣obj的引用計數變為0,銷毀。如果前面那條語句[obj release]不寫,則obj的對象沒有正常釋放掉,就會造成記憶體流失!

(2)需要先釋放掉數組裡的所有對象,然後再釋放NSMutableArray對象嗎?

答:不需要。

在釋放NSMutableArray對象裡,它自動先給裡面的對象發一個release訊息。

(3)正確使用NSMutableArray的步驟是什麼? (alloc, init, work, release) 

答:

1. NSMutableArray *arr = [[NSMutableArray alloc] init];   //分配數組

2. alloc object1.              //分配obj1

3. add object1 to array.    //把obj1加到數組中

4. release object1.           //obj1引用計數減1

5. alloc object2.               //分配obj2

6. add object2 to array.    //把obj2加到數組中

7. release object2.            //obj2引用計數減1

8. add as many objects as needed in this manner.  // 按上面的辦法,可以加任意多的對象

8. work with object1.        //可以訪問裡面的對象

9. remove object1 from array. it will receive a release automatically.  //也可以把obj1移除,這時obj1會自動收到一個release訊息

10. [arr release];   // object2 and others will receive a release.  最後釋放數組,數組裡的所有元素也會自動得到一個release訊息

上述道理對於NSMutableDictionary類的setObject方法也適用。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.