self.navigationController pushViewController不将控制器添加到堆栈

Spa*_*Dog 4 iphone uiviewcontroller ipad ios

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

[self.navigationController pushViewController:vcB animated:YES];
Run Code Online (Sandbox Code Playgroud)

它的工作原理.vcB被推了.在vcB的viewDidAppear里面我这样做:

NSArray *controllers = self.navigationController.viewControllers;
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢.

Spa*_*Dog 8

我把头撞在墙上一个星期来解决这个问题,包括推动导航控制器堆栈上的视图控制器.

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

我正在用vA从vA推送vB:

[self.navigationController pushViewController:vB animated:YES];
Run Code Online (Sandbox Code Playgroud)

它工作,但是,当我尝试从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];

};
Run Code Online (Sandbox Code Playgroud)

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

解决方案是将推送包装到主线程中,使用:

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

};  
Run Code Online (Sandbox Code Playgroud)

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