跳转控制器 push 和 modal 的区别

stack.jpg

写这篇的起因是这样的,朋友小朱写了个控制器 modal 出来,里面用到了 NSTimer 然后他想 dealloc 的时候关闭 timer(由关闭通知监听想到) ,可是就发现该控制器 dissmiss 的时候代码根本不走这里,出现了内存泄露。我建议他在viewWillDisappear之前需要把 NSTimer 销毁了就可以了。再检查下有没有使用 Block 引用实例变量即可解决。可是这让我想到了个问题,控制器跳转的两种方式的区别,好像并不能一下说的很清楚。

所以,首先我来谈谈 push 的管理方式。

NavigationController

  1. 一种最常见的情况 A 控制器上有个按钮 push 到 B 控制器 它上又有个按钮 push C 控制器 这里的内部机制是这样的:
    1.1 每个 NavigationController 都会对应一个 栈 来管理其子控制器,每 push 一个进来就压栈(先进后出),放到栈顶。如下图所示:
    NavigationControllers.png

    1.2 一旦有控制器进栈,可以简单的理解为:就把这个控制器所对应的 View 创建出来,放到 NavigationController's View 上,若不是栈顶控制器的话,则把之前 NavigationController's View 移除(注意并没有销毁),再添加。如下图所示:
    PushViewController.png

    现在就可以得出一个结论:
    结论一:显示在导航栏控制器的 View 永远是栈顶控制器的 View。
    1.3 我们再来看从 C控制器 返回到 A控制器,每返回一个就出栈一个,然后把其控制器销毁。如下图所示:
    popViewController.png

    从上面一系列的分析来看,则可以发现,一个导航控制器对应一个导航条,即多个子控制器共用一个导航条。
    结论二:导航控控制条的内容由栈顶控制器决定(navigationItem)

Modal

2.为了搞清楚 Modal 的原理,我觉得自己撸一个就差不多了。这里给一个我做的过程:
2.1 把控制器的 View 加到 window 上;
2.2 使用 transform 向下平移一个屏幕高度,再清空 transform 完成动画。


CustomModal.png

2.3 由于控制器的创建都是在函数内部完成的,所以函数执行完毕后就内存就回收了。所以如果该控制器还有操作的话,就会 EXC_BAD_ACCESS 所以我要添加一个属性来强引用 ModalVC。
所以就发现 Modal 出的控制器是需要被强引用的,通过看文档也可以发现 Modal 出的控制器会被当前控制器的 presentViewController 保存(强引用)。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1> 什么是多控制器之间的跳转? 在一个 APP 中,会存在多个控制器,多个控制器的存在就会存在控制器的跳转问题....
    Brice_Zhao阅读 3,616评论 0 2
  • 之前一直有些疑惑,到底控制器的不同的展示形式有什么区别,今天就查了一些资料,做了一个小结。 在一个app中,会存在...
    可乐小子阅读 8,087评论 0 2
  • 说了很多难懂的东西,究竟如何自定义任意一个VC的状态栏前景颜色呢?我机智的把结果放到最前面,后面自己的摸索过程,想...
    半江瑟瑟阅读 11,997评论 3 7
  • 前言的前言 唐巧前辈在微信公众号「iOSDevTips」以及其博客上推送了我的文章后,我的 Github 各项指标...
    VincentHK阅读 10,767评论 3 44
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 175,079评论 25 709