NSMutableArray实例变量内存管理

Chr*_*ris 2 memory-management objective-c nsmutablearray

我正在做最后一点内存管理整理,有些事我不明白.我已经检查了所有文档,Stack Overflow等,但仍然没有得到它.我怀疑它与数组有关.

我有一个NSMutableArray实例变量,用于保存从另一个数组中的对象创建的对象.

-viewDidLoad 按如下方式初始化数组:

self.photoAlbum = [[NSMutableArray alloc] initWithCapacity:100];
Run Code Online (Sandbox Code Playgroud)

然后它调用一个填充它们的方法.

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++;
}
Run Code Online (Sandbox Code Playgroud)

在仪器中,它显示我正在泄漏Photo物体,我不知道为什么.

photoAlbum物业是:

@property (nonatomic, retain) NSMutableArray *photoAlbum;
Run Code Online (Sandbox Code Playgroud)

我错过了什么?

Jon*_*ing 7

问题是你的属性的setter有retain语义.您需要autorelease在设置属性时,如下所示:

self.photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] autorelease];
Run Code Online (Sandbox Code Playgroud)

或者,甚至更好:

self.photoAlbum = [NSMutableArray arrayWithCapacity:100];
Run Code Online (Sandbox Code Playgroud)

这种情况的原因是你通过合成该属性生成的setter看起来像这样(简化):

- (void)setPhotoAlbum:(NSMutableArray *)array {
  [photoAlbum autorelease];
  photoAlbum = [array retain];
}
Run Code Online (Sandbox Code Playgroud)

那么,发生的事情是:

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

// in -dealloc:
[photoAlbum release]; // 2 - 1 = 1
Run Code Online (Sandbox Code Playgroud)

因此,photoAlbum永远不会释放足够的时间来解除分配,因为-release看起来像这样(大大简化):

- (void)release {
  retainCount = retainCount - 1;
  if (retainCount == 0) {
    [self dealloc];
  }
}
Run Code Online (Sandbox Code Playgroud)

(我想重申,这基本上就是实现的目的,而不是现实生活中的样子).重点是,在你的发布与保留之间取得平衡之前,你不会触发解除分配.

永远不要把这当作永远的劝诫-retainCount.运行时存在的其他对象可能会保留您的对象并使用您不了解的对象进行操作; 因此,在任何给定时间对象的实际保留计数对您来说都是无用的.请永远不要在管理内存时使用它.@bbum会谢谢你.