IOS视图控制器导航及生命周期研究演示

  

1,背景:

2014年4月份第一次接触IOS端开发,为某银行开发一款金融应用。
在开发的最后阶段,加入了需要从任意一个页面直接返回主页的功能。
悲催的是,当时没有使用UINavigationController进行导航管理,而是使用了IOS中的模态跳转方式(<强> presentViewController/dismissViewControllerAnimated )。

因此需要找的一种方法进行,实现如下方式的导航跳转:

已知:页面一个→页面b→页面c
求解:页面c直接跳回到页面,并且要求不能有内存泄露,循环依赖等

2,解题思考:

面对上面的需求,最简单的方式是将所有控制器都改成UINavigationController,并且利用<强> pushViewController/popToViewController popToRootViewControllerAnimated 等方法进行完美解题。但是当时项目的页面将近100个,分成三大模块,需要大规模修改设计页面以及调整大量代码,这并不是一个现实的解决方案,不到万不得已,不能采取如此低劣手段!

我们需要一个满足如下条件的解决方案:

 1),对于已经在InterfaceBuilder中完成的页面,不做任何修改
  2),尽量少的修改代码,因为很多代码已经经过测试中心测试过,如果修改,需要全部重新测试,时间来不及。

当时通过两天的研究,深入的了解了IOS中的跳转流程和生命周期后,找到了一个相对完美的解决方案,能够满足上面提到的要求。通过一个演示,来和大家一起分享。

3,解题流程:

 1),为了减少代码的修改,增加一个基类。
 @interface  BaseViewController : ui//防止控制器循环引用,使用弱引用方式
  @ property(原子、弱),BaseViewController *, parentController;//为了能够了解某个页面控制器生命周期相关信息,给该控制器取个名字
  @ property(原子、复制),,,NSString *,,, ctrlName;//关键的函数,进行页面c,在跳转到主页
  (空白),doDismiss;
  
  @end以前 <>前2),为了更好的了解IOS中ViewController的生命周期,我们在基类中输出相关信息来了解生命周期相关信息。
 @implementation  BaseViewController
  
  - (id),初始化
  {
  ,,,self.ctrlName =, @ ";
  ,,,self.parentController =,零;
  ,,,return  [super  init];
  }
  
  安康;viewDidLoad (void)
  {
  ,,,NSLog (@ % @  invoke  viewDidLoad, self.ctrlName);
  ,,,(super  viewDidLoad);
  ,,,//,Do  any  additional  setup  after  loading 从而视图。
  }
  
  - (void)那些:(BOOL)动画
  {
  ,,,NSLog (@ % @  invoke 那些,self.ctrlName);
  ,,,(super 那些:动画);
  }
  
  - (void) viewDidAppear: (BOOL)动画
  {
  ,,,NSLog (@ % @  invoke  viewDidAppear, self.ctrlName);
  ,,,(super  viewDidAppear:动画);
  }
  
  (空白),viewWillDisappear: (BOOL)动画
  {
  ,,,NSLog (@ % @  invoke  viewWillDisappear, self.ctrlName);
  ,,,(super  viewWillDisappear:动画);
  }
  
  (空白),viewDidDisappear: (BOOL)动画
  {
  ,,,NSLog (@ % @  invoke  viewDidDisappear, self.ctrlName);
  ,,,(super  viewDidDisappear:动画);
  }
  
  安康;didReceiveMemoryWarning (void)
  {
  ,,,NSLog (@ % @  invoke  didReceiveMemoryWarning, self.ctrlName);
  ,,,(super  didReceiveMemoryWarning);
  ,,,//,Dispose  of  any  resources  that 还要be 重新创建。
  }
  
  - (void) dealloc
  {
  ,,,NSLog (@“% @  ....... dealloc .......”, self.ctrlName);
  }
 3),关键的递归函数,核心是理解dismissViewControllerAnimated:完成函数中完成回调的时机点,这个是解题的钥匙。
 - (void) doDismiss
  {
  ,,,NSLog (@ % @  dismiss 开始,self.ctrlName);
  
  ,,,如果([self.parentController  isKindOfClass: [ViewController 类]])
  ,,,{
  ,,,,,,,(self  dismissViewControllerAnimated: YES 完成:^(空白)
  ,,,,,,,,{
  ,,,,,,,,,,,,NSLog (@ % @  dismiss 最终,self.ctrlName);
  
  ,,,,,,,,,,,,如果(self.parentController)
  ,,,,,,,,,,,,{
  ,,,,,,,,,,,,,,,,(self.parentController  doDismiss);
  ,,,,,,,,,,,,}
  ,,,,,,,,}];
  ,,,}
  ,,,
  ,,,{
  ,,,,,,,(self  dismissViewControllerAnimated: NO 完成:^(空白)
  ,,,,,,,,{
  ,,,,,,,,,,,,NSLog (@ % @  dismiss 最终,self.ctrlName);
  
  ,,,,,,,,,,,,如果(self.parentController)
  ,,,,,,,,,,,,{
  ,,,,,,,,,,,,,,,,(self.parentController  doDismiss);
  ,,,,,,,,,,,,}
  ,,,,,,,,}];
  
  ,,,}
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null
  null

IOS视图控制器导航及生命周期研究演示