【问题标题】:Why does releasing a view controller cause a crash?为什么释放视图控制器会导致崩溃?
【发布时间】:2011-09-08 00:35:00
【问题描述】:

我总是像这样将新的视图控制器推送到堆栈上:

 MyViewController *vc = [[MyViewController alloc] init];

[self.navigationController pushViewController:vc animated:YES];

[vc release];

当它从堆栈中弹出时,一切都很好:

[self.navigationController popViewControllerAnimated:NO];

但是现在当我将 vc 从堆栈中弹出时,我在 main.m 中遇到了崩溃,说明在 line:int retVal = UIApplicationMain(argc, argv, nil, nil); 处访问不正确

但是现在如果我注释掉 [vc release] 就不会再崩溃了?

但是为什么而且肯定会泄漏内存,因为我没有释放我创建的东西?

【问题讨论】:

  • 您是否尝试在调试模式下运行它?找出它崩溃的确切行。也许这与发布根本无关,因为您发布的代码似乎是正确的
  • 从您的控制台发布详细消息,如果您不介意,MyViewController 的代码可能会有所帮助。
  • 请发布回溯。崩溃不在那条线上;它在汇编程序的某些行中,大约 20 个堆栈帧进一步向下。您发布的代码很好,所以您在其他地方做错了对视图控制器的引用计数或它递减的对象之一不合适的事情,很可能是在-dealloc-viewDidUnload 期间递减的对象之一。回溯应该准确地告诉您您做错了什么类型的对象。

标签: iphone uiviewcontroller uinavigationcontroller release exc-bad-access


【解决方案1】:

也许您对 vc 内部某些内容的内存管理不善。

@brandontreb 的这句话对我很有帮助!在“收到模拟内存警告”后,我花了一整天的时间来修复崩溃,具体描述如下:
Preventing bad access crash for popViewControllerAnimated in uinavigationcontroller setup

在我推送的视图控制器的 loadView: 中,将视图控制器自身传递给它的数据源的 init:。

LayoutPickerDataSource *pickerDataSource = [[LayoutPickerDataSource alloc] initWithController:self];

而 dataSource 类将其保留为:

@property (nonatomic, retain) LayoutViewController *viewController;

修复崩溃只需更改为:

@property (nonatomic, assign) LayoutViewController *viewController;

并删除:

[viewController release];

宾果游戏!我还是不知道为什么!作为 viewController 在 dealloc: of dataSource 中发布的。

【讨论】:

    【解决方案2】:

    它们不同的原因是您没有分配文本对象,因此您不是所有者。分配和重新分配它们是 IB 的工作,它确实如此。

    所以如果你也尝试释放它,它会导致问题。

    【讨论】:

      【解决方案3】:

      您的内存管理看起来不错。也许您对 vc 内部某些内容的记忆管理不善。 MyViewController 的 dealloc 方法是什么样的?

      我的猜测是您使用了不正确的 init 方法(可能是 initWithNibName:bundle:),并且您在 dealloc 中释放了从未正确初始化的 ivars。

      【讨论】:

      • 所以我使用了 initWithNibName 并且不再崩溃!这对我来说是一个新的,因为无论 IB 还是手动创建,我总是使用 init。这仍然让我有点不知所措......我标记了这篇文章并作为答案,虽然其他人也说同样的话,我认为我不能将多个帖子标记为答案?感谢大家的投入并指出我的缺陷! ;-)
      【解决方案4】:

      导航控制器将保留vc,然后,当vc 被弹出时,navigationController 释放它并vc 释放。

      所以,你必须留下发布代码,这是正确的。

      我认为您必须使用 initWithNibName:bundle: 插入 init

      【讨论】:

      • 不,我认为他在推动 VC 后调用发布是正确的。如果您使用 IB 构建 VC,则应该使用 initWithNibName 否则 init 很好。
      • 我只是说他必须在推送 VC 后调用 release :) 对于 initWithNibName 可能是我的错。
      • 哦大声笑对不起我的错我以为你告诉他不要释放它.....这就是缺乏咖啡对我的影响!
      【解决方案5】:

      你试过把它当作一个

      @property
      

      【讨论】:

      • 使用@property(非原子,保留)
      • 不,我不认为将此视图控制器设为属性会有所帮助。我感觉这次崩溃与他没有发布的代码有关......
      猜你喜欢
      • 1970-01-01
      • 2021-04-14
      • 2011-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-07
      • 1970-01-01
      • 2021-06-28
      相关资源
      最近更新 更多