【问题标题】:Objective-C memory management - pretty sure I'm doing this all wrongObjective-C 内存管理 - 很确定我做错了
【发布时间】:2011-01-14 04:18:46
【问题描述】:

大约 3 个小时后,我终于设法修复了视图控制器中的内存泄漏。泄漏是由 UIPickerView 引起的,该 UIPickerView 在头文件中将其属性设置为“保留”。

以下代码设法修复它:

- (void)viewDidLoad {
    [super viewDidLoad];    
    myPicker = [[[UIPickerView alloc] initWithFrame:CGRectZero]autorelease];
}

- (void)dealloc {
    [super dealloc];
    [myPicker release];
    myPicker = nil;
}

请不要告诉我这段代码有多令人震惊……我知道这很糟糕。我有一个发布,一个自动发布。问题是,如果我更改或删除上述任何部分,内存泄漏就会返回。

虽然我知道客观的 C 内存管理是如何工作的,但显然不知道......

为什么上面的代码修复了内存泄漏,正确版本的代码是什么样的?

-

编辑:

如果有人遇到同样的问题或感兴趣 - 问题是我班级中的其他对象之一被设置为“保留”而不是“分配”。 (如果你不拥有一个对象,它应该有属性分配,而不是保留)。

就像 Cannondale 所说,删除额外的保留可以解决所有问题,并且只需要一个版本。

【问题讨论】:

标签: iphone objective-c memory-management


【解决方案1】:

您必须在代码中的其他位置对 myPicker 进行保留。一旦堆栈展开 viewDidLoad 调用,您的 myPicker 分配行将释放该内存(这就是 autorelease 告诉它做的事情)。

在那之后您必须在某处进行保留,否则您的 [myPicker 版本] 将尝试释放未分配的内存,结果无法预测。

你应该做的是在 viewDidLoad 中分配内存(所以删除自动释放)。确保不要在其他任何地方保留对象并从 dealloc 中释放 myPicker。

还有...bbum 所说的关于 dealloc ;)

【讨论】:

  • 谢谢 - 很有意义!非常感谢:) 现在,只是为了找到额外的保留...
  • myPicker 是您在接口文件中创建的属性吗,您可能是retaining?这是我的猜测。
【解决方案2】:

Cannonade 说的。这应该有效:

myPicker = [[UIPickerView alloc] initWithFrame:CGRectZero];

你的dealloc 也被破坏了。对super 的调用始终必须在最后(考虑一下),这可能会导致未定义的行为。

- (void)dealloc {
    [myPicker release];
    myPicker = nil;
    [super dealloc];
}

【讨论】:

  • 那还是很优雅的。我认为是时候为我学习 ObjC 了。
  • 这里没有必要将 myPicker 设置为 nil。这是您最后一次可以引用它,因此不会有意外取消引用它的危险。
  • 确实如此;我最终出于习惯以[foo release], foo = nil; 这样做。时不时地让调试变得更容易(如果我需要在 dealloc 之外发布,我可以三次单击复制/粘贴)。
猜你喜欢
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多