2011-04-01 85 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