【问题标题】:UINavigationController is nil after pop弹出后 UINavigationController 为零
【发布时间】:2013-07-15 14:46:00
【问题描述】:

我的项目很复杂(可能有点太多了)但问题很简单,这里是代码

...
self.vc = [[ClassName alloc] init];
if ([[self.navigationController.viewControllers lastObject] isKindOfClass:[ClassName class]]) {
    [self backAndGo:self.vc title:@"Title"];
}
else {
    [self vai:self.vc title:@"title"];
}
...

在这段代码中,如果当前视图与ClassName 不同,我必须直接进入下一个视图,否则返回前一个视图并转到下一个。

- (void)backAndGo:(id)view title:(NSString *)title

- (void)backAndGo:(id)view title:(NSString *)title
{
    NSLog(@"before %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);

    [self.navigationController popViewControllerAnimated:NO];

    ALCParentViewController *viewController = (ALCParentViewController *)view;
    [self.navigationController pushViewController:viewController animated:YES];

    NSLog(@"after %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);
}

ALCParentViewController 是 vc 的父类,在此方法中,navigatin 控制器的第一个日志对所有视图控制器堆栈都是正确的,popViewController 被执行但在第二个日志中,navigatin 控制器显然是 0 元素的 null,并且pushViewController 方法没有执行,为什么?有什么想法吗?

- (void)vai:(id)view title:(NSString *)title

- (void)vai:(id)view title:(NSString *)title
{       
    ALCParentViewController *viewController = (ALCParentViewController *)view;
    [self.navigationController pushViewController:viewController animated:YES];
}

这是直接到达第二个视图的另一种方法,它可以正常工作,另一件事(几乎对我来说)是尽管 nil pushviewcontroller,其他视图中的导航(推送和弹出)正常工作......

编辑 1:

正如 lucaslt89 所说,我在第二个日志中放置了一个断点,并在控制台中创建了“po self.navigationController”,这里是结果

(lldb) po self.navigationController
$0 = 0x00000000 <nil>
(lldb)

它是零,但我可以在没有断点的日志中看到...

编辑 2:

(lldb) po self.navigationController
$0 = 0x099787d0 <UINavigationController: 0x99787d0>
(lldb) po auxNavController
$1 = 0x099787d0 <UINavigationController: 0x99787d0>
(lldb)

经过lucaslt89提示的操作,两个地址是一样的

【问题讨论】:

  • 可能在 popViewController 之后,您对 navigationController 的引用为零。在第二条日志中打断点,在控制台打“po self.navigationController”查看输出,贴在这里!

标签: ios pushviewcontroller navigationcontroller


【解决方案1】:

根据您上次的编辑,一种解决方案是保存对导航控制器的引用。你的 backAndGo 方法应该是这样的

- (void)backAndGo:(id)view title:(NSString *)title
{
    NSLog(@"before %@,%d",[self.navigationController viewControllers],[[self.navigationController viewControllers] count]);

    UINavigationController *auxNavController = self.navigationController;

    [self.navigationController popViewControllerAnimated:NO];

    ALCParentViewController *viewController = (ALCParentViewController *)view;
    [auxNavController pushViewController:viewController animated:YES];

    NSLog(@"after %@,%d",[auxNavController viewControllers],[[auxNavController viewControllers] count]);
}

如果你调试的话,在pop之前self.navigationController的地址应该和在pop之后的auxNavController一样。试试看,告诉我们你的结果!

【讨论】:

  • 好的 lucaslt89 我已经完成了你所说的部分工作,但是我回到家后的视图,无论我打电话回AndGo的视图是什么......无论如何,谢谢你的帮助;)跨度>
  • 不抱歉,它就像一个魅力......但我不知道为什么......你获得支票的任何方式:)
【解决方案2】:

好的,即使问题已经结束,我也想为未来的访问者做一个解释。根据documentation:...如果视图控制器未嵌入导航控制器,则此属性为零。

这正是你使用 pop 指令所做的。因此,基本上,在因为弹出而丢失对导航控制器的引用之前,请确保存储对它的引用。

【讨论】:

    【解决方案3】:

    在您的 backAndGo 方法中: 首先你弹出一个viewController,然后你推送另一个ViewController。

    问题是,在你弹出一个 viewController 之后,“self”是 nil。因此,如果您使用“self.navigationController”获取导航控制器,它将不会返回任何内容。

    原因是因为“self”是nil,而不是navigationController 是空的。这就是为什么 lucastl89 的答案是有效的。他通过引用持有一个navigationController 对象,而不是使用“self”来搜索它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多