4

我在一个名为 vcA 的 viewController 上,我这样做:

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

它有效。vcB 被推送。在 vcB 的 viewDidAppear 里面我这样做:

NSArray *controllers = self.navigationController.viewControllers;

控制器只包含一个对象,vcA !!!! (什么?)

为什么将 vcB 添加到控制器阵列中?有什么可以防止这种情况发生吗?

谢谢。

4

2 回答 2

8

为了解决这个涉及在导航控制器堆栈上推送视图控制器的问题,我苦苦挣扎了一周。

问题是这样的:我在一个基于导航控制的应用程序上,我有 3 个视图控制器,vA、vB 和 vC。

我正在使用这个从 vA 推送 vB:

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

它起作用了,但是,当我尝试从 vB 推送 vC 时,vB 的 self.navigationController 属性为 nil 并且 vB 不在导航控制器堆栈上。什么?是的,我将 vB 推送到导航堆栈上,并且 vB 没有被添加到其中,但即便如此,vB 仍能正确显示。

我发现在 vB 的 viewDidLoad 内部,self.navigationController 不是 nil,并且 vB 在导航控制器堆栈上,但是一旦 vB 的 viewDidLoad 结束,vB 就从导航控制器堆栈中删除,并且它的 navigationController 属性设置为 nil。那时,vB 是一种幽灵控制,在导航控制器堆栈之外。

我不需要提到从 vB 中我无法回到 vA 或推动 vC。

这是怎么发生的?

简单,我是从一个块内推 vB ......类似于:

void (^ block1)() = ^(){

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

};

发生了什么,因为 UIKit 函数(推送的东西)正在一个块中执行,该块可能在一个不是主线程的线程上运行。

对此的解决方案是将推送包装到主线程的调度中,使用以下方法:

void (^ block1)() = ^(){
dispatch_async(dispatch_get_main_queue(),
               ^{
                   [self.navigationController pushViewController:vB animated:YES];
               });

};  

该应用程序还有另一个小问题,即连接到 viewController 的错误插座,但这是主要问题。这是一种很难发现的问题,因为它很微妙。当我向导航栏添加另一个按钮并且该按钮没有出现时,我发现了这个问题。所以,我怀疑涉及 UIKit 的事情正在发生,或者在这种情况下没有发生。这里最大的问题是这段代码没有崩溃,没有错误消息,什么都没有,只是工作不好,但工作正常。

于 2012-11-08T00:18:38.363 回答
2

我相信这与您检查的时间有关。在该pushViewController方法期间,下一个视图控制器的 viewWillAppear: 方法(以及其他方法,例如您正在检查的方法)正在被调用。我相信在调用所有这些方法之后,在动画完成后,视图控制器会被考虑在导航堆栈上。

于 2012-11-07T21:57:49.793 回答