2011-04-01 84 views
2

我正在做最後一點的內存管理整理,有些東西我不明白。我已經檢查了所有的文檔,堆棧溢出等,但仍然沒有得到它。我懷疑這是與數組有關的。NSMutableArray實例變量內存管理

我有一個NSMutableArray作爲一個實例變量,我用它來保存從另一個數組中的對象創建的對象。

-viewDidLoad初始化數組如下:

self.photoAlbum = [[NSMutableArray alloc] initWithCapacity:100]; 

它然後調用該填充它們的方法。

int i = 0; 
for (Gem *gem in self.entityArray) { 
    NSString * filePath = [[NSString alloc] initWithFormat: @"%@/%@2.jpg", [sysPaths objectAtIndex: 0], gem.detailsTitle]; 
    // there is some stuff in here that means that there isn't a one to one relationship between the objects in gem and those in photo 
    Photo *photo = [[Photo alloc] init]; 
    photo.filePath = filePath; 
    photo.title = gem.title; 
    photo.index = [NSNumber numberWithInt:i]; 
    [self.photoAlbum addObject:photo]; 
    [filePath release]; 
    [photo release]; 
    i++; 
} 

儀表,它顯示我泄露Photo對象,我不知道爲什麼。

photoAlbum屬性是:

@property (nonatomic, retain) NSMutableArray *photoAlbum; 

我缺少什麼?

回答

7

問題是你的財產的設置者有retain語義。你需要autorelease當您設置的屬性,像這樣:

self.photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] autorelease]; 

,或者甚至更好:

self.photoAlbum = [NSMutableArray arrayWithCapacity:100]; 

原因是這種情況下,你已經通過合成產生的二傳手屬性看起來像這樣(簡化):

- (void)setPhotoAlbum:(NSMutableArray *)array { 
    [photoAlbum autorelease]; 
    photoAlbum = [array retain]; 
} 

那麼,什麼正在發生的事情是:

[photoAlbum autorelease]; 
photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] retain]; // 0 + 2 = 2 

// in -dealloc: 
[photoAlbum release]; // 2 - 1 = 1 

因此,photoAlbum是永遠不會釋放足夠的時間被釋放,因爲-release看起來是這樣的(大量簡化):

- (void)release { 
    retainCount = retainCount - 1; 
    if (retainCount == 0) { 
    [self dealloc]; 
    } 
} 

(我要重申,這是基本上是落實在做什麼,但不是現實生活中的樣子)。關鍵是,只有在您的發佈與您的保留之間保持平衡之後,纔會觸發釋放。

不要把這個當作一個告誡,永遠看看-retainCount,永遠。在運行時存在的其他對象可能會保留你的對象並對它做些你不知道的事情;因此,在任何給定時間對象的實際保留計數對您而言都是無用的。請不要在管理內存時使用它。 @bbum會感謝你。

+3

+1爲底部的大膽位! – walkytalky 2011-04-01 16:39:55

+0

謝謝喬納森。這是數組特有的嗎?我的@property聲明是最合適的嗎? – Chris 2011-04-01 16:57:37

+2

該代碼嚇了我一秒。 – bbum 2011-04-01 19:49:04

-1

你可能缺少

[photoAlbum release]; 
在dealloc方法

編輯

其實,我錯了。有問題的行是

self.photoAlbum = [[NSMutableArray alloc] initWithCapacity:100]; 

您創建的數組是您擁有的數組,但您不會釋放它。這將修復它:

self.photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] autorelease]; 
+0

不,它在那裏! – Chris 2011-04-01 15:52:30

+0

是的,問題不是'-dealloc',而是他設置了一個保留的對象,它在setter中被再次保留。 – 2011-04-01 15:53:40

+0

讓它更加簡單:self.photoAlbum = [NSMutableArray array]; 「initWithCapacity」有很少的收穫。通常代碼越少越好。 – zaph 2011-04-02 11:57:04