iphone(object-c) 內存管理(3) 有效的內存管理 後半部分 – iPhone手機開發技術文章 iPhone軟體開發教學課程

不要使用dealloc管理稀缺資源

 

你不應該使用dealloc方法去管理像文件描述符,網絡連接以及緩存之類的稀缺資源。特別是,你不應該去設計類想當然的認為dealloc將會在你認為的地方觸發。dealloc的觸發可能由於bug或者程序的崩潰被延遲或者規避掉。

 

相反,如果你有一個類的實例管理稀缺資源,那麼你應該設計你的程序去告訴實例變量在適當的時候去清理資源,然後再去調用dealloc來釋放實例變量。如果dealloc沒有被調用,你就不會遭受比較嚴重的問題。

 

當你在dealloc方法中去管理資源時,問題可能就會出現。例如:

1.    對象圖銷毀的順利依賴

對象圖銷毀機制內在是沒有順利,雖然你可能期望有一個特定的順序,但通常這是不可靠的。如果一個對象不合適宜的落入瞭自動釋放池中,對象的銷毀順序可能會改變,這會導致意想不到的問題

2.    沒有回收稀缺資源

內存泄露的問題需要被解決,但是它們通常並不立刻引發致命的問題。如果一個稀缺資源沒有在你想讓它釋放的時候釋放掉,那麼你可能遇到嚴重的問題。例如當你的程序用光瞭文件描述符,用戶就不能保存數據瞭。

3.    清理邏輯在錯誤的線程中被執行

如果一個對象在一個錯誤的時間被放入瞭自動釋放池中,它可能會被釋放掉而不會管它碰巧是在哪一個線程池中。這可能是致命的,因為這個對象本改隻被另一個線程訪問。

 

LPSTUDY:

            說實話,這一段讀起來有一點拗口,太理論化瞭。我的理解是:當你管理稀缺資源的時候,不要在dealloc中做。比如你想在dealloc去釋放文件描述符,但是可能由於程序的bug原因,dealloc沒有被執行,也就是說這個文件描述符沒有被釋放。如果這個dealloc需要被執行多次,也就有很多你想釋放的文件描述符沒有被釋放掉。這樣很明顯是錯誤的。當然上面說的有三種dealloc引起的問題,我僅僅是舉瞭第二種例子。總的來說:不要用dealloc管理稀缺資源,換句話說,不要太相信dealloc的執行。

 

收集類擁有(retain)它們包含的對象

當你向一個收集類(例如數組,詞典或者集合)添加瞭一個元素,那麼這個收集類就擁有瞭這個元素。當你調用收集類的remove方法,或者此收集類自身被釋放的時候,這個收集類釋放元素的所有權。因此,如果你想創建一個數組,你可以采用以下方式:

NSMutableArray *array = <#Get a mutable array#>;

NSUInteger i;

// …

for (i = 0; i < 10; i++) {

    NSNumber *convenienceNumber = [NSNumber numberWithInteger:i];

    [array addObject:convenienceNumber];

}

上面的這種情況沒有調用alloc,因此也沒有必要調用release。你也不需要調用retain方法,因為array已經做瞭。 www.aiwalls.com

 

NSMutableArray *array = <#Get a mutable array#>;

NSUInteger i;

// …

for (i = 0; i < 10; i++) {

    NSNumber *allocedNumber = [[NSNumber alloc] initWithInteger: i];

    [array addObject:allocedNumber];

    [allocedNumber release];

}

上面的這種你調用瞭alloc方法,故而在addobject之後,你需要調用release方法。在addobject中,array已經對allocedNumber調用瞭retain操作。

 

如果你想更好的理解上面的機制,那麼請你站在收集類設計者的角度上來看待它。因為你想確保你的收集類不依賴於外部傳入進來的元素是否在以後的某一個時刻被釋放瞭,於是你在元素傳入進來的時候調用瞭retain操作。如果它們被移除瞭,你為瞭平衡添加的時候的retain,於是調用瞭release操作。在收集類的dealloc方法中,你應該對所有剩下的元素調用release方法。

 

擁有策略是通過引用計數實現的。

擁有機制通過引用計數實現,每一個對象有一個引用計數

·     當你創建瞭一個對象,它的引用計數是1

·     當你對此對象發送retain消息,它的引用計數增1

·     當你發送release消息,引用計數減1

當你發送autorelease消息,它的引用計數會在未來的某一個時候減1

·     如果一個對象的引用計數為0,它會被釋放掉

 作者:lipeng08

發佈留言