2012-05-07 26 views
0

我來自C背景,很多人都知道Objective-C是從C派生的。我認爲內存管理概念是相似的。我收到了關於潛在內存泄漏的警告,但奇怪的是,我在alloc之後釋放該對象。在這個例子看看:iPhone應用程序中的內存泄漏

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]; 

,並在的dealloc:

- (void) dealloc 
{ 
[super dealloc]; 
[self.cardCellArray removeAllObjects]; 
} 

內存泄漏的消息我越來越有:

Method returns an Objective-C object with a +1 retain count

Object leaked: allocated object is not referenced later in this execution path and has a retain count of +1

任何人都可以發現我在這裏做錯了嗎?

回答

1
  1. 檢查。如果是這樣,當你調用self.cardCellArray,對象設置財產cardCellArray得到保留計數由1

  2. 創建使用alloc & init(如initWithCapacity:)返回與保留計數1對象對象增加,因爲你在這裏調用了一個alloc方法。

    儘管沒有調用創建對象alloc[NSMutableArray arrayWithCapacity:]將返回autorelease對象(它會自動降低它在需要的時候通過1保留計數),你可以考慮它在方法dealloc保持數0

  3. ,你應該調用[self.cardCellArray release],這會自動刪除數組保留的所有對象。

你的代碼在這裏產生一個保留-數-1對象後

[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]

這個對象的保留計數成爲2,當你調用

self.cardCellArray = xxx

但是在dealloc中,你並沒有減少cardCellArray的保留計數t母雞泄漏發生。

所以你的代碼更改爲

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease];

自動釋放會自動降低在需要時保留計數。

self.cardCellArray = [NSMutableArray arrayWithCapacity:kTotalNumberOfCards];

NSMutableArray *_array = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]; 
self.cardCellArray = _array; 
[_array release]; 

cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]; 
//this helps because it doesn't call `[self setCardCellArray]` which generate +1 retain count. 

最後,請記住在dealloc方法來釋放cardCellArray

3

您不釋放數組,而只是清空它。 另請注意,我將[super dealloc]調用移入最後一行,這是因爲具有其實例變量的對象在dealloc鏈中稍後完全釋放,因此您將嘗試訪問釋放的內存。

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

另一件事:您正在使用self.cardCellArray =,這取決於伊娃您@property的樣子,你可能有,因爲它保留了對象去除self.部分(或者你有以後手動釋放)。 @property的保留對象是copyretain

+0

removeallobjects吧?我只是用這個作爲例子,我有很多其他人有點莫名其妙地讓我發佈其中一個 – godzilla

+0

@godzilla更新我的回答 – JustSid

+0

啊所以如果我有@property(nonatomic,retain)NSMutableArray * uncontrolledCards;並做一self.cardCellArray =我實際上覆制不傳遞參考? – godzilla

4

我假設cardCellArray屬性是擁有引用(即保留或複製)。

self.cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]; 

這應該是:

self.cardCellArray = [[[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards] autorelease]; 

甚至:

cardCellArray = [[NSMutableArray alloc] initWithCapacity:kTotalNumberOfCards]; 

爲確保存儲管理是正確的。

此外,dealloc方法應該是:

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

這假定爲cardCellArray屬性的實例變量被命名爲cardCellArray。

1

是的,正如JustSid建議您雙重保留數組並永不釋放它。

雖然Objective-C堆管理在C中有根,但是管理單個對象的方式完全不同。

你不說怎麼財產cardCellArray定義,但據推測它定義爲retained,使得當分配給self.cardCellArray,你真的執行方法setCardCellArray,並且該方法「保留」的對象。但由於您的電話號碼已被保留,所以現在它保留兩次。

然後,在dealloc方法你根本不release它。您可以通過執行[cardCellArray release];或執行self.cardCellArray = nil;來釋放對象。要麼釋放它(但只有一次 - 你需要用雙重保留來解決你的問題)。

你做需要做​​電話。當release對象(並且保留計數爲零)時,會調用該對象的dealloc方法,並執行適用於其引用對象的版本。

(正如希德建議,做[super dealloc]最後調用。)

(當然,以上的一切都是出於與ARC,在這裏你不用擔心一個完全新的和不同的一套東西的窗口中如果屬性是cardCellArrayretain可以copy搞砸。)

+0

感謝您的迴應,你可以請告知以下內容:如果我有一個NSString與保留屬性,我做了一個[self setFileName:[[NSString alloc] initWithFormat:@「Pentagon.png」]];我是否分配了兩次? – godzilla

+0

@godzilla - 你會保留兩次。 'alloc'基本上就像C中的malloc一樣,只是它對原始對象頭進行了一些額外的設置,其中一部分是對保留計數進行增量。 (你真的需要在Objective-C上找到一本好書(或者至少是一本書),並研究堆管理的東西 - 這不是你可以在街上輕鬆拾取的東西。) –