重复调用UINavigationController的push会导致访问错误

时间:2010-09-18 15:35:55

标签: uinavigationcontroller ios exc-bad-access

我有一个带有选项卡的TabView应用程序,该选项卡有一个NavView作为其中一个视图。此视图有一个带有TableView的子视图来保存事件。我已启用导航栏右上角的“添加”按钮,并将IBAction分配给按钮。

目标是显示一个页面来添加一个新事件,该事件由我实例化我的子类控制器类的实例时加载的NIB文件定义。我也从父导航控制器传递了managedObjectContext。

这是第一次使用,但第二次按“添加”按钮时出现EXC_BAD_ACCESS错误。我调试了将控制器推到导航控制器上,我已经确认这是异常发生的地方。我已经阅读了文档,它说导航控制器会通过点击导航栏顶部提供的“后退”按钮来弹出控制器。我也知道如果我尝试将相同的视图压入堆栈,将会发生未处理的异常。我甚至尝试在推送清除堆栈之前弹回root,但仍然在第二次推送时获得异常。

我应该在其他地方手动弹出这个(即导航“后退”按钮实际上没有弹出这个)吗?我也确认导航控制器和新实例化的视图控制器的实例都不是空的。

以下是添加按钮的代码段:

- (IBAction) addEvent: (id)sender {

 // Here we'd instantiate an instance of our Add Event Controller to show the form that allows us to enter a new event.

 // We'd add the context to the class from here so that it can get to our Core Data


  EventEntryViewController *fvController = [[EventEntryViewController alloc] initWithNibName:@"AddEventView" bundle:nil];

 fvController.managedObjectContext = self.managedObjectContext;

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

 [fvController release];

 fvController = nil;

}

感谢您的帮助。

更新

好的,我已经停止了异常的发生。我尝试了一个非常简单的视图,其中没有任何内容,没有IBOutlets或IBActions以及没有属性的控制器类。这有用,所以我认为它必须是我的EventEntryViewController的问题。它没有做太多,后面的跟踪显示它在显示视图的内部死亡,所以我甚至没有得到loadView方法,更不用说我的代码的任何其他部分了。我有一些在前一次加载中初始化的类属性,作为一个好公民,我在viewDidUnload()中释放它们并在dealloc()中释放它们。当我注释掉我的类属性的dealloc时它起作用了!

我对此感到困惑,并在viewDidLoad(),viewDidUnload()和dalloc()中放置了NSLog()行。这是我拿出我的类属性的dallocs后两个推送序列的结果:

2010-09-18 20:17:46.224 myFuel[6435:207] EventTableNavViewController: viewDidAppear
2010-09-18 20:17:51.391 myFuel[6435:207] **EventEntryViewController**: View Did Load // loading up my class
2010-09-18 20:17:53.954 myFuel[6435:207] EventTableNavViewController: viewWillAppear
2010-09-18 20:17:54.314 myFuel[6435:207] EventTableNavViewController: viewDidAppear
2010-09-18 20:17:54.315 myFuel[6435:207] **EventEntryViewController**: dalloc       // after the class should have been popped
2010-09-18 20:18:02.803 myFuel[6435:207] **EventEntryViewController**: View Did Load //loading up my class
2010-09-18 20:18:08.134 myFuel[6435:207] EventTableNavViewController: viewWillAppear
2010-09-18 20:18:08.494 myFuel[6435:207] EventTableNavViewController: viewDidAppear
2010-09-18 20:18:08.495 myFuel[6435:207] **EventEntryViewController**: dalloc    // after the class should have been popped

我在这里遗漏了什么吗?视图是否应该调用viewDidUnload()从而释放类属性?我可以看到dealloc被调用,但我在哪里发布这些?

1 个答案:

答案 0 :(得分:0)

基于你所说的话,有几件事情,虽然我不清楚你到底在做什么。

首先,viewDidUnload:不能保证被调用。通常,只有在视图控制器卸载它的视图以响应内存警告时才会调用它。因此,您在viewDidLoad:或任何连接的IBOutlet中保留引用的任何内容都应该在viewDidUnload:dealloc中发布。

其次,你说你在dealloc中“取消分配它们”,指的是你的“类属性”,我认为你实际上是在其他对象上调用dealloc。如果是这样的话......不要那样做。您只能在保留的对象上调用release,并且在直接调用dealloc时很少会有实例。这是因为dealloc将在最后一次释放时在release的对象实现中被调用。这就是保留/释放系统的重点。