为了解决这个涉及在导航控制器堆栈上推送视图控制器的问题,我苦苦挣扎了一周。
问题是这样的:我在一个基于导航控制的应用程序上,我有 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 的事情正在发生,或者在这种情况下没有发生。这里最大的问题是这段代码没有崩溃,没有错误消息,什么都没有,只是工作不好,但工作正常。