2012-01-21 127 views
1

我已經讀過,將調用一個對象的dealloc,只有當該對象的保留計數變爲零時纔會被調用。iOS內存泄漏

我在接口部分以一個對象UIColor和設置屬性

UIColor *currentColor; 
@property (nonatomic, retain) UIColor *currentColor; 

在implemetation部分使用這個對象後,我呼籲釋放的方法該對象在dealloc

-(void)dealloc 
{ 
    [currentColor release]; 
    [super dealloc]; 
} 

我懷疑dealloc將如何被調用這個對象,因爲我沒有在任何地方釋放保留的對象。提前致謝。

回答

2

將被調用,只要保留該對象的 計數變爲零,最好的地方我讀過的dealloc的對象。

是的。

爲了簡單起見,請將包含currentColor對象的類稱爲ColorContainer。現在,如果你創建的ColorContainer像下面的一個實例:

ColorContainer* containerColor = [[ColorContainer alloc] init]; // retain count + 1 

containerColor保留計數變爲1。

假設您創建了一個UIColor的實例,並將該實例設置爲currentColor屬性。在這種情況下,您可以採用兩種不同的方式。 在第一個中,您可以創建如下的實例。如果您使用像initWithRed:green:blue:alpha:這樣的實例方法,則必須明確釋放內存。

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 because you use a retain policy 
[color release]; // retain count -1, now the referenced object has a retain count of 1 

在第二種方法中,您可以使用類方法(+符號)。在這種情況下,您不需要釋放內存顯式,因爲在該類方法中創建的對象將在應用程序生命週期的某個時間點自動釋放。

containerColor.currentColor = [UIColor whiteColor]; // retain count +1 

現在假設您發佈了containerColor對象。如果containerColor的保留計數等於1,則將其從使用該對象的對象中釋放,它允許調用其dealloc方法,因此也可以消除由currentColor引用的對象。

在你要注意到,currentColor引用的對象是完全從內存(解僱)移除了這個簡單的案例,只有當它有保留的。事實上計數,如果你這樣做

UIColor color* = [[UIColor alloc] initWithRed:0 green:0 blue:0 alpha:1]; // retain count + 1 
containerColor.currentColor = color; // retain count +1, the referenced object has a retain count of 2 
//[color release]; 

你創建了一個內存泄漏(你明白了嗎?)。

總之,當你使用retaincopyinitnew(這是相同的alloc-init),你必須總是叫對口releaseautorelease

作爲一個經驗法則,您需要總是平衡對象的保留計數以避免內存泄漏。

所以,作爲一個美眉,你可以像樹一樣思考記憶。假設你有一個父母(containerColor)和一個孩子(currentColor)。如果父(保留計數爲1)被釋放,它會導致爲其對象調用其dealloc方法和空閒內存。如果在其dealloc方法中釋放一個子項(保留計數爲1),它會導致調用其dealloc方法和空閒內存。如果孩子的保留數大於1,則會導致內存泄漏。

希望它有幫助。

編輯

對於你能讀懂About Memory Management進一步的信息。自iOS 5 Apple推出ARC以來,自動引用計數是一種編譯器機制,提供Objective-C對象的自動內存管理。有關信息,請參閱Transitioning to ARC Release Notes

+0

Hello Flex,非常感謝您的回答。 – karthick

+0

不客氣! –

0

如果您分配對象(通過alloccopyretain),則應該只在對象上調用release。具有retain屬性的屬性將自動爲您進行內存管理,只要您正確處理它們即可。只能通過self.currentColor訪問它們。根據您創建顏色對象的方式,您可能會或可能不會使用release,但是您的總是應該在您的dealloc方法中將屬性設置爲nil。舉兩個例子:

// If you use this (or some other way to get the color without alloc, copy or retain) 
// then you do not need to do any release 
self.currentColor = UIColor.blackColor; 
self.currentColor = [UIColor colorWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 

// On the other hand if you get it like this, you have to release/autorelease the object 
self.currentColor = [[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0]; 
[self.currentColor release]; 
// or better 
self.currentColor = [[[UIColor alloc] initWithRed:1.0 green:0.5 blue:0.2 alpha:1.0] autorelease]; 

// dealloc always the same 
-(void)dealloc{ 
    [currentColor release], currentColor = nil; 
    [super dealloc]; 
} 

這裏有兩個重要的事實:

  1. 對於每個alloccopyretain你的代碼的問題,你必須發出releaseautorelease

  2. 總是使用self.currentColor來訪問該屬性,而不是currentColor除非取消分配。這裏的事情是,當使用self.currentColor時,系統自動添加內存管理代碼。只要設置了self.currentColor,它就自動地retain s和release s的對象。只有在最終釋放時,您應該直接設置變量,更多信息請參閱this answer on the topic(感謝Flex_Addicted)。

+0

在dealloc方法中調用'self.currentColor = nil;'可能會產生如[release-or-set-to-nil-retained-members]中所建議的問題(http://stackoverflow.com/questions/5358134/release - 或 - 設置爲零保留成員)和[MemoryMgmt蘋果文檔](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmPractical.html# // apple_ref/doc/uid/TP40004447-SW1) –

+0

謝謝,相當有趣的想法。我會相應地編輯我的帖子。 –

+0

不客氣。 –

2

當您使用保留currentColor屬性setter你retain該對象,如果你retaincopyalloc內存的對象,你必須將其釋放。 -(void)dealloc是做