我正在做最后一点内存管理整理,而且我有些不明白。我已经检查了所有文档,Stack Overflow等,但仍然没有得到它。我怀疑它与数组有关。
我有一个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++;
}
在Instruments中,它显示我正在泄漏Photo
个对象,我不知道为什么。
photoAlbum
属性为:
@property (nonatomic, retain) NSMutableArray *photoAlbum;
我错过了什么?
答案 0 :(得分:7)
问题是你的属性的setter有retain
个语义。在设置属性时需要autorelease
,如下所示:
self.photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] autorelease];
或者,甚至更好:
self.photoAlbum = [NSMutableArray arrayWithCapacity:100];
这种情况的原因是你通过合成该属性生成的setter看起来像这样(简化):
- (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会感谢你。
答案 1 :(得分:-1)
你可能不见了
[photoAlbum release];
在dealloc方法中。
修改强>
实际上,我错了。有问题的一行是
self.photoAlbum = [[NSMutableArray alloc] initWithCapacity:100];
您创建的阵列是您拥有的阵列,但您不会释放它。这将解决它:
self.photoAlbum = [[[NSMutableArray alloc] initWithCapacity:100] autorelease];