坏编程的后果:dismissViewController与popViewController的区别

21
我了解dismissViewControllerAnimated:completion:popViewControllerAnimated:的区别,如在Stack Overflow和这里所述:

-dismissViewControllerAnimated:completion:方法用于关闭由-presentViewController:animated:completion:方法呈现的UIViewController。

-popViewControllerAnimated:方法是UINavigationController用于取消-pushViewController:animated方法显示的控制器。

最近我在我的应用程序中发现了一个错误,我使用[self dismissViewControllerAnimated:completion:]来关闭一个在导航嵌入式应用程序中通过push呈现的VC。我犯了错误,因为一切都正常工作,我的VC按预期被释放了。 我的问题:混淆这两种方法的后果是什么?
2个回答

22

-presentViewController:animated:completion:-pushViewController:animated: 意思不同。前者表示“展示另一个视图控制器以替代你自己”。后者表示“将另一个视图控制器显示在你内部,作为你正在控制的列表的一部分”。

所以这是关于在转换后谁被认为负责显示的问题。在前一种情况下,导航控制器放弃控制权。而在后一种情况下,它保留控制权。

前一种功能由UIViewController提供。后者是特定于UINavigationController的。

由于这两个操作非常不同,相反的行为需要单独处理。导航控制器可以捕获dismissViewController:...并检查命名控制器是如何呈现的,然后根据情况分支超类或pop... ,但混淆任务在设计和维护方面都不可取。

由于导航控制器没有承诺将一个东西映射到另一个东西,而UIViewController如果传递的控制器以前没有被呈现,也没有承诺任何特定的行为,因此我认为您问题的字面答案是:混淆这两件事的后果是未定义的行为。


谢谢。-presentViewController:animated:completion 属于 UIViewController。如果您没有导航控制器,那么您根本不需要使用-pushViewController:animated,对吗? - Jeff T

1

我不确定是否能够最好地解释这个问题,但让我试试。

我现在正在开发一个基于选项卡的应用程序,每个选项卡都有自己的导航控制器。对于侧边功能,我在导航栏上有一个barbuttonitem,可以展开到模态视图(在某些情况下是到全新的导航控制器来控制特定功能路径的后退堆栈)。

我将在另一个导航控制器上启动时调用dismissViewController方法。(我希望这样说起来更清楚。)

也许这样更好:

呈现视图控制器负责关闭它所呈现的视图控制器。如果您在呈现的视图控制器本身上调用此方法,则它会自动将消息转发给呈现视图控制器。

如果您连续呈现多个视图控制器,从而构建了一个呈现的视图控制器堆栈,那么在堆栈中较低的视图控制器上调用此方法将关闭其直接子视图控制器和该子视图控制器上方的所有视图控制器。当发生这种情况时,只有最顶部的视图以动画方式关闭;任何中间视图控制器都将被简单地从堆栈中移除。最顶部的视图使用其模态转换样式关闭,这可能不同于堆栈中较低的其他视图控制器使用的样式。

推荐使用基于导航的视图控制器,并在需要时使用popViewController。对于从导航中分支出的任何内容,应该以模态方式引入,并在这种情况下根据需要使用dismissViewController。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接