注:本文根据个人的实践和理解写成,若有不当之处欢迎斧正和探讨!

addChildViewController是一个从iOS5开始支持的api接口,相关的一系列的接口是用来处理viewcontroller中嵌套显示其他viewcontroller的场景的。

在出现此api之前,大家可能会使用addsubview并持有viewcontroller对象的方式来实现这个需求,控制多个viewcontroller的view的hidden标签达到同时只显示1个子viewcontroller和切换子viewcontroller的目的。

相关主要api一览:

1.- addChildViewController:

加入子viewcontroller。

2.- removeFromParentViewController

将自身从父viewcontroller中移除(脱离关系)

子viewcontroller切换示例:

3.    [self transitionFromViewController:self.currentViewController
                          toViewController:selectedVC
                                  duration:0
                                   options:UIViewAnimationOptionTransitionNone
                                animations:nil
                                completion:nil];

4.willMoveToParentViewController:
5.didMoveToParentViewController:

6. 一个只读属性:childViewControllers , 可以用来获取此容器viewcontroller当前拥有的全部childviewcontroller。

其中1和2很容易理解;就是建立/解除viewcontroller之间的父子关系(注意:实际使用时还是要结合调用addsubview来把视图加进来)。
3:当1个容器viewcontroller中加入多个child时,使用该api来切换childviewcontroller,并可以设置动画效果和结束事件处理,很方便。

其中4和5就有些奇怪了,光从命名来看可能会以为是子viewcontroller即将隐藏和已经隐藏时触发的方法,但实际上我们阅读其api发现情况不是这样。

看下苹果官方文档:

willMoveToParentViewController:

Called just before the view controller is added or removed from a container view controller.

Discussion
Your view controller can override this method when it needs to know that it has been added to a container.

If you are implementing your own container view controller, it must call the willMoveToParentViewController: method of the child view controller before calling the removeFromParentViewController method, passing in a parent value of nil.

When your custom container calls the addChildViewController: method, it automatically calls the willMoveToParentViewController: method of the view controller to be added as a child before adding it.



didMoveToParentViewController:

Called after the view controller is added or removed from a container view controller.

Discussion
Your view controller can override this method when it wants to react to being added to a container.

If you are implementing your own container view controller, it must call the didMoveToParentViewController: method of the child view controller after the transition to the new controller is complete or, if there is no transition, immediately after calling the addChildViewController: method.

The removeFromParentViewController method automatically calls the didMoveToParentViewController: method of the child view controller after it removes the child.



这里如果暂时先不考虑“implementing your own container view controller”,看一下苹果实现的container view controller, 最典型的莫过于 navigationcontroller了。
那么我们这里可以联想一下,可能navigationcontroller相关的pop、push也是基于这一套api机制来实现的。
我们在demo里面打印通过navigationcontroller push出来的界面的生命周期方法(包括willMoveToParentViewController和didMoveToParentViewController),
我们发现:
界面push进来时:
willMoveToParentViewController
viewdidload
didMoveToParentViewController

界面退出时:
willMoveToParentViewController
didMoveToParentViewController
dealloc

再结合上面api的两句话:
willMoveToParentViewController:

Called just before the view controller is added or removed from a container view controller.  在viewcontroller被添加或者移除之前时被调用;

didMoveToParentViewController:

Called after the view controller is added or removed from a container view controller. 在viewcontroller被添加或者移除之后被调用。

再来看“implementing your own container view controller”时的情况,我们仅仅通过1、2、3来使用这一套api,那么实际测试发现当child被加入到parent的时候只会触发willMoveToParentViewController,而当child被移出parent的时候只触发了didMoveToParentViewController方法。

再仔细看下苹果api文档说明:
在“implementing your own container view controller”时,将自己从父viewcontroller移除之前,需要手动调用willMoveToParentViewController;
同样的,将自己加入父viewcontroller以后(或者从其他子viewcontroller页面迁移而来时)需要手动调用didMoveToParentViewController(时机在addchild或者迁移的completion结束以后)。

综上,我们可以分析知:willMoveToParentViewController、didMoveToParentViewController可以用来帮助我们进行一些页面跳转相关的生命周期业务逻辑处理,但其存在一些问题不可不察:
1.需要准确的理解这两个方法触发的时机
2.对于系统的container,这两个方法一定会在适当的时机触发;而对于自己实现的container,必须要在适当的时机手动调用这两个方法,才能保证其触发的完备性。如果你不手动调用,那么你也要准确的理解在这种场景下什么时候会触发
3.从一个开发者角度来说,我认为这两个api的设计比较失败。首先其命名并不能直观表达出其触发场景;且其使用上也有诸多限制。因此对于调用者来说,建议仅在不使用这两个api就无法满足业务需求时才使用这两个api。

最后:推荐一个国人的UI框架,写的很用心,其中addChildViewController相关api还有其他一些转场之类的api使用,可以作为很好的学习参考。 https://github.com/tianzhuo112/VTMagic

addChildViewController相关api深入剖析的更多相关文章

  1. OpenGL FrameBufferCopy相关Api比较(glCopyPixels,glReadPixels,glCopyTexImage2D,glFramebufferTexture2D)

    OpenGL FrameBufferCopy相关Api比较 glCopyPixels,glReadPixels,glCopyTexImage2D,glFramebufferTexture2D 标题所述 ...

  2. QQ音乐的各种相关API

    QQ音乐的各种相关API 分类: oc2014-01-29 15:34 2676人阅读 评论(2) 收藏 举报 基本上论坛里做在线音乐的都在用百度的API,进来发现百度的API不仅歌曲的质量不可以保证 ...

  3. [原创]java WEB学习笔记44:Filter 简介,模型,创建,工作原理,相关API,过滤器的部署及映射的方式,Demo

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  4. 关于iOS中用AudioFile相关API解码或播放AAC_HE_V2时仅仅能识别单声首22.05k採样率的问题

    关于iOS中用AudioFile相关API解码或播放AAC_HE_V2时仅仅能识别单声首22.05k採样率的问题 在官方AQPlayer Demo 和 aqofflinerender中.都用了Audi ...

  5. TCP/IP协议栈源码图解分析系列10:linux内核协议栈中对于socket相关API的实现

    题记:本系列文章的目的是抛开书本从Linux内核源代码的角度详细分析TCP/IP协议栈内核相关技术 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswang@gmail.com linu ...

  6. 【Socket编程】Java中网络相关API的应用

    Java中网络相关API的应用 一.InetAddress类 InetAddress类用于标识网络上的硬件资源,表示互联网协议(IP)地址. InetAddress类没有构造方法,所以不能直接new出 ...

  7. java 11 移除的一些其他内容,更简化的编译运行程序,Unicode 10,移除了不太使用的JavaEE模块和CORBA技术,废除Nashorn javascript引擎,不建议使用Pack200 相关api

    移除的一些其他内容 移除项 移除了com.sun.awt.AWTUtilities 移除了sun.misc.Unsafe.defineClass, 使用java.lang.invoke.MethodH ...

  8. python 以单例模式封装logging相关api实现日志打印类

    python 以单例模式封装logging相关api实现日志打印类   by:授客QQ:1033553122 测试环境: Python版本:Python 2.7   实现功能: 支持自由配置,如下lo ...

  9. 029 RDD Join相关API,以及程序

    1.数据集 A表数据: 1 a 2 b 3 c B表数据: 1 aa1 1 aa2 2 bb1 2 bb2 2 bb3 4 dd1 2.join的分类 inner join left outer jo ...

随机推荐

  1. 一张广告图片引起的思维DFS

    1.概述 今天老同事发了一张图片, 结果后面有几个家伙回了“中毒了...”“这是挖墙脚的节奏么”(对了,这个老同事也离职了). 本来也想说上几句的,发现激情难在. 不过,最近了解到DIP.DM.ML. ...

  2. BZOJ3463 : [COCI2012] Inspector

    考虑将序列分成$\sqrt{n\log n}$块,每块维护下凸壳,修改时在相应块打上需要修改的标记. 查询时,对于两端零散部分暴力查询. 对于中间的块,如果有修改标记,则暴力重构. 然后在凸壳上查询时 ...

  3. 【BZOJ】1221: [HNOI2001] 软件开发(最小费用最大流)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1221 先吐槽一下,数组依旧开小了RE:在spfa中用了memset和<queue>的版本 ...

  4. Python小例子

    import urllib.request as request import urllib.parse as parse import string print(""" ...

  5. placeholder在不同浏览器下的表现及兼容方法

    1.什么是placeholder?    placeholder是html5新增的一个属性,当input或者textarea设置了该属性后,该值的内容将作为灰字提示显示在文本框中,当文本框获得焦点(或 ...

  6. easyui datagrid 增删改查示例

    查询JSP页面 <!doctype html> <%@include file="/internet/common.jsp"%> <!-- 新样式右侧 ...

  7. 通过程序校验xml文档学习笔记

    校验xml文档,可以通过程序来校验,利用一段js代码即可. 各行代码的含义已经写出,运行这个html文件,检验如下xml代码: 结果如下: 如果xml文档出现错误: 结果如下: 其中,obj.asyn ...

  8. LINUX 2.6.18-238 local root exp

    /* * * * 1-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=0 * 0 _ __ __ __ 1 * ...

  9. WSUS更新服务器

    http://windowsupdate.microsoft.com http://*.windowsupdate.microsoft.com   https://*.windowsupdate.mi ...

  10. tomcat从下载到使用

    话说,某天正在和周公聊天下大事.被急促的电话铃声召唤回来,所谓江湖救急,于是远程一看.竟然是需要使用tomcat(汤姆家的猫),于是... 下面关于下载和配置tomcat的过程. ①.使用tomcat ...