【问题标题】:Iphone - is controller freed after push?Iphone - 推送后控制器是否被释放?
【发布时间】:2009-08-06 13:48:35
【问题描述】:

当我调用另一个控制器时,我的 UIViewController 是否被释放? 当我推送到另一个控制器时如何释放控制器的内存?由于内存不足(无泄漏),我需要超过 40 个月和申请休假。

[self.navigationController pushViewController:[[MainListController alloc] init:self] animated:NO];

@interface MainListController : UIViewController
...
- (id)init: (id)ref;

当我调用init函数时,控制器的dealloc是:

[ref dealloc];

我有这个错误:

objc[70754]: FREED(id): message isEqual: sent to freed object=0xe216b0
Program received signal:  “EXC_BAD_INSTRUCTION”.
  • (void)dealloc {[super dealloc];}

【问题讨论】:

  • @Nicolas:您在上面发布的这段代码绝对是泄漏的。 navigationController 保留了您的控制器,您正在创建它而不在那里自动释放它。每次以这种方式推动控制器时,您都会绝对泄漏。您必须执行以下操作: [self.navigationController pushViewController:[[[MainListController alloc] init:self] autorelease] animated:NO];
  • 另外,请确保您在视图控制器的 init:self 调用中的代码不会保留您传递给它的变量,否则您将有一个保留周期,具体取决于此导航控制器的方式/位置已创建,也可能会泄漏。
  • 我不会失去记忆,因为我再也没有回到这个控制器,这就是我想要释放它的原因!你有其他解决方案吗?
  • 是:MainListController* mlc = [[MainListController alloc] init:self]; [self.navigationController pushViewController:mlc Animation:NO]; [mlc 发布]; ——本该如此。导航控制器将在不再需要时释放它。

标签: iphone cocoa-touch xcode


【解决方案1】:

在将新视图控制器推送到导航堆栈时,您不能(也不应该)释放/释放父视图控制器。您可以通过回复didReceiveMemoryWarning 消息来卸载视图。

您的代码还有其他几个问题:

  1. 永远不要手动拨打[obj dealloc]。始终使用[obj release]
  2. 您的init 方法名称应该更具描述性,以免与预定义的init 方法冲突。如果需要使用 ref 参数,您还应该(可能)强输入它。像(id)initWithParent:(UIViewController*)ref 这样的东西会更好。
  3. 您的代码正在泄漏MainListController 对象,因为您正在分配/初始化它,然后将其交给navigationController。将您的代码更改为[[[MainListController alloc] initWithParent:self] autorelease]

【讨论】:

    【解决方案2】:

    不,您不能释放不可见的 UIViewControllers。当顶部的控制器弹出导航控制器时会发生什么?操作系统会显示什么?

    相反,您应该在所有控制器中实现didReceiveMemoryWarning 方法。这些应该release(不是dealloc)尽可能多的缓存数据。任何可以重新计算或从磁盘带回的东西都应该考虑在内。

    这比deallocing 视图更好,因为您真的不知道提前有多少可用内存。在 iPhone 3GS 上,即使使用 40Mb,您也可能有足够的内存。

    【讨论】:

    • 仅仅因为你可以并不意味着你应该。如果你真的想在切换到 MainListController 时释放内存,为什么不在调用 pushViewController 方法之前释放内存呢?
    • 如果我打电话给[自我释放];在 [self.navigationController pushViewController:[[MainListController alloc] init:self] animated:NO] 之前它的工作,你确定,我不会坏访问?因为我释放了自我,在我做了 self.navigation 之后......谢谢
    • 不,当 UIViewController 仍在导航控制器堆栈中时,您不能释放它。你需要释放缓存的数据,而不是控制器本身。
    • 我在另一个要求做 self.view = nil;是视图,所有子视图都将在我的控制器上发布吗?非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    相关资源
    最近更新 更多