在loadNibNamed中存在内存泄漏问题?

6

我即将完成我的第一个iPhone应用程序,并决定使用Leaks性能工具来测试它。在修复了一个明显的问题之后,我只剩下一个问题,那就是使用loadNibNamed加载的表头视图中存在一个内存泄漏(我是根据Recipes示例操作的)。


- (void)viewDidLoad {
    [super viewDidLoad];

    if (self.tableHeaderView == nil) {
        [[NSBundle mainBundle] loadNibNamed:@"TableHeaderView" owner:self options:nil];
        self.tableView.tableHeaderView = self.tableHeaderView;
    }
}

接下来在dealloc方法中:


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

Instruments告诉我,我正在泄漏256个字节,其中2个泄漏来自使用loadNibNamed的行。tableHeaderView是Nib中唯一的顶级对象(我已在调试器中验证)。我是否忘记了释放某些东西?我是否误解了Instruments告诉我的内容?它是错误的吗?还是操作系统会稍后清理它?


1
你没有启用NSZombieEnabled吧?这会在Instruments中显示错误的泄漏信息。 - nall
不过如果这是我需要额外去做的事情,那我就不会去做。默认情况下是关闭吗? - AndrewO
好的,很棒。我因此而疯狂了。我的程序出现了僵尸进程。 - RyeMAC3
2个回答

4

加载nib文件时,您需要释放该文件中所有顶级对象。除了TableHeaderView外,在该文件中是否还有其他内容?


不是的 - 我已经验证它是nib文件中唯一的顶级对象。 - AndrewO
你听起来好像知道你在说什么,但我没有在任何地方找到这个记录。实际上,loadNibNamed的文档中指出:“你应该手动保留返回的数组或其中包含的对象,以防止nib文件对象过早释放。” - 你能详细说明/参考一下吗?非常感谢! - Oded Ben Dov

2

仪器是否只在模拟器上报告这个问题,或者它也在实际设备上报告相同的问题?如果你在设备上没有遇到这个问题,那么它就是模拟器的问题 - 这种情况已经被证实会发生(它并不完全匹配)。

此外,在dealloc中,应该是 [self.tableHeaderView release] 吗?你必须保持一致性。

为了避免混淆,在你的.h文件中,你应该声明这个:

NS/UI/??xxxxxx *_MyObjectName;   //notice the underscore

然后是这样的属性:
@property .... NS/UI/??xxxxxx *MyObjectName;   //no underscore

然后像这样综合使用getters/setters:
@synthesize MyObjectName=_MyObjectName;

最后,通过[self.MyObjectName ...];在整个程序中引用该对象。

设备相关的问题:我正在设置我的设备以进行实际测试,当我完成后会更新。我尝试将dealloc中的释放调用更改为使用self,但没有任何变化。我记得在某个地方读到过应该避免在dealloc中使用属性语法(虽然我猜不使用self调用也不会更好),或者只是setter方法? - AndrewO
我倾向于不更改本地属性的版本,除非我必须这样做(比如它是只读的)。否则,我总是使用self来访问它。我建议看一下苹果的示例,但即使是最基本的学习应用程序也有同样的弱点。至少:如果你保持这种纪律,以后可以使用查找/替换将其切换到其他内容。要么正确,要么错误,只要保持一致!玩得开心!设备配置文件也很有趣!最好使用苹果的指南-真的。 - inked
下划线的目的是什么? - RyeMAC3
下划线被一些人用来表示变量是类的实例变量。 - yabada

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接