说到导航的push,pop操作,想必写代码的我们基本每天都可能会用到,前两天遇到一个问题,某些界面我需要pop到上级的上级界面,起初我的想法很简单,那就是[[self.navigationController popViewControllerAnimated:NO].navigationController popViewControllerAnimated:YES];
但是没效果,还是pop到上级界面了,并没有pop到上级的上级界面,然后我想着这样行不通,那得,我就用找到对应的那个controller,然后pop到这个界面:
UIViewController *target = nil;
for (UIViewController * controller in self.navigationController.viewControllers) {
if ([controller isKindOfClass:[YourViewControllerName class]]) {
target = controller;
}
}
if (target) {
[self.navigationController popToViewController:target animated:YES];
}
当然了,这样也是解决问题了,但是我后来在review代码的时候,总感觉这样很累赘,没道理嘛,简单的一个出栈操作,肯定是简单的pop就可以搞定的啊,然后我细心考量了下我之前的哪行pop代码。What a fuck man! 原来是这样,[[self.navigationController popViewControllerAnimated:NO].navigationController popViewControllerAnimated:YES];
我们先看第一行[self.navigation popViewControllerAnimated:NO],这是把当前的ViewController从当前栈中做pop操作,会从当前栈中移除,那会发生什么问题呢?问题就是当前的VC被销毁了,然后接着看后边的代码 .navagationViewController,肯定就没有什么意义了啊,不用说肯定是nil啊,我们对nil对象发送一个消息指令,objc_msgSend(object, SEL op, ...),对啊,object都是nil了,发消息指令还有用吗?
解决方法:
我们需要在这个VC pop之前先把当前的navigationController保存下来,然后利用这个导航做两个pop操作即可!可以像下边这样修改上边的代码:
UINavigationController *nav = self.navigationController;
[self.navigationController popViewControllerAnimated:NO];
[nav popViewControllerAnimated:YES];
我们苹果的runtime在给nil发送指令的时候是不会crash的,但是在对一个存在的对象发送一个此对象没有对应的消息指令的时候是会crash的,所以虽然说给nil发送指令(nil调方法)不会crash,但是真要是有这种bug出现的时候其实还是不好找的,切记:判断对象是否为nil是很有必要的!
网友评论