无线客户端框架设计(4):自定义生命周期的设计(iOS篇)

移动开发 iOS
熟悉网站端编程的人笑了,没错,这种新的生命周期,就是从javascript中借鉴来的。js是一门弱语言,所以需要自定义生命周期并按部就班在不同的方法中写不同的方法,生命周期的重新定义,或者说是扩展,只是js代码框架中的一个小部分。

首先要确定一点,我们的App,要基于XIB文件进行编程,而不是在每个相应的ViewController里面去手动创建页面的每个控件。这样做 的好处是,将页面布局与业务逻辑彻底隔离。于是我们可以把xib的绘制工作交给美工人员,而iOS程序员,主要关心的是业务逻辑。

有人会怀疑过多的xib会导致App体积变大,我曾经有专门看过ipa文件解压后的文件列表,我发现每个xib也就2k大小,而一个App最多也就 七八十个xib,那么就是说共计150k大小的样子,由于是xml文本文件,所以压缩后更小。而相比较下,占用App体积最多的,往往是开机画面图,引导 图这些东西,如果真的想要App瘦身,应该在图片上进行优化,而不是不使用xib直接布局。

另一个需要明确的是,在一开始创建ViewController的时候,不要同时创建xib文件,因为这样子的话,就在xib中把 ViewController和xib进行关联了,而我们要做的是解耦,这显然不合理。所以正确的流程是,分开创建ViewController和 xib,不要进行管理。在ViewController的初始化中,加载xib文件,如下所示:

接下来要做的事情,有时候连我都觉得匪夷所思。我们先来看一段代码:

  1. #import "APageViewController.h" 
  2.  
  3. @interface APageViewController () 
  4.  
  5. @end 
  6.  
  7. @implementation APageViewController 
  8.  
  9. - (void)loadView 
  10.     [super loadView]; 
  11.     // Do any additional setup after loading the view. 
  12.  
  13.     //1.从xib中获取View 
  14.     NSArray* list = [[NSBundle mainBundle] loadNibNamed: @"APageView" owner: self options: nil]; 
  15.     self.view = list.lastObject; 
  16.      
  17.     UILabel* nameLabel = (UILabel*)[self.view viewWithTag: 100]; 
  18.     nameLabel.text = @""
  19.      
  20.     UILabel* ageLabel = (UILabel*)[self.view viewWithTag: 200]; 
  21.     ageLabel.text = @""
  22.      
  23.     UIButton* getInfoButton = (UIButton*)[self.view viewWithTag: 300]; 
  24.     [getInfoButton addTarget: self action: @selector(getInfo) forControlEvents:UIControlEventTouchUpInside]; 
  25.      
  26.     UIButton* clearInfoButton = (UIButton*)[self.view viewWithTag: 400]; 
  27.     [clearInfoButton addTarget: self action: @selector(clearInfo) forControlEvents:UIControlEventTouchUpInside]; 
  28.  
  29. - (void) getInfo { 
  30.     UILabel* nameLabel = (UILabel*)[self.view viewWithTag: 100]; 
  31.     nameLabel.text = @"包小强"
  32.      
  33.     UILabel* ageLabel = (UILabel*)[self.view viewWithTag: 200]; 
  34.     ageLabel.text = @"31.6"
  35.  
  36. - (void) clearInfo { 
  37.     UILabel* nameLabel = (UILabel*)[self.view viewWithTag: 100]; 
  38.     nameLabel.text = @""
  39.      
  40.     UILabel* ageLabel = (UILabel*)[self.view viewWithTag: 200]; 
  41.     ageLabel.text = @""
  42.  
  43. - (void)dealloc { 
  44.     [super dealloc]; 
  45.  
  46. @end 

上面的代码,是再普通不过的一段代码,读取一个xib,获取到View的句柄,初始化其中的每个控件,为按钮挂上点击后的方法事件,使得按钮变红。 内部还有个计数器变量,每次点击按钮都会加1。巧的是,恰好还要侦听一个通知(Notification)。最后,调用API。

我们发现,有2个问题:

1)在willDidLoad中做了太多的事情,又是初始化变量,又是初始化控件,又是给按钮挂事件,注册通知,还要调用API。

2)每次使用控件时,都要根据在xib中指定的tag重新获取,而iOS中的控件tag值,只能是整数。

我们的解决方案是,既然页面每次加载都会调用loadView和viewDidLoad方法,每次销毁都会调用dealloc方法,那么干脆就在基类BaseViewController重写了这几个方法,于是现在页面的生命周期如下所示:

201309051002.jpg

相应的基类代码请参见本章的源码。

我们在每个页面都会重写createFields、loadData这些方法,每个方法的意义如下:

1)createFields和destroyFields: 创建/销毁页面级变量的地方。

2)createViews和destroyViews: 创建/销毁页面内控件的地方。

3)createEvents和destroyEvents: 创建/销毁页面内事件、通知的地方。

4)loadData: 如果页面加载过程需要调用MobileAPI,则写在这个地方。

我们在程序里把代码分门别类写在各自的地方,易于管理(避免了经常会声明了变量而忘记销毁的问题)。

于是刚才的代码文件,我们将其重构为:

  1. #import "APageViewController.h" 
  2.  
  3. @interface APageViewController () { 
  4.     UILabel* nameLabel; 
  5.     UILabel* ageLabel; 
  6.     UIButton* getInfoButton; 
  7.     UIButton* clearInfoButton; 
  8.  
  9. @end 
  10.  
  11. @implementation APageViewController 
  12.  
  13. - (void)createFields { 
  14.  
  15.  
  16. - (void)destroyFields { 
  17.      
  18.  
  19. - (void)createViews { 
  20.     //1.从xib中获取View 
  21.     NSArray* list = [[NSBundle mainBundle] loadNibNamed: @"APageView" owner: self options: nil]; 
  22.     self.view = list.lastObject; 
  23.      
  24.     nameLabel = (UILabel*)[self.view viewWithTag: 100]; 
  25.     nameLabel.text = @""
  26.      
  27.     ageLabel = (UILabel*)[self.view viewWithTag: 200]; 
  28.     ageLabel.text = @""
  29.      
  30.     getInfoButton = (UIButton*)[self.view viewWithTag: 300];     
  31.     clearInfoButton = (UIButton*)[self.view viewWithTag: 400]; 
  32.  
  33. - (void)destroyViews { 
  34.      
  35.  
  36. - (void)createEvents { 
  37.     [getInfoButton addTarget: self action: @selector(getInfo) forControlEvents:UIControlEventTouchUpInside]; 
  38.     [clearInfoButton addTarget: self action: @selector(clearInfo) forControlEvents:UIControlEventTouchUpInside]; 
  39.      
  40.  
  41. - (void)destroyEvents { 
  42.      
  43.  
  44. - (void)loadData { 
  45.     //在这里调用API,对于多个API的调用,参加后续章节 
  46.  
  47. - (void) getInfo { 
  48.     nameLabel.text = @"包小强"
  49.     ageLabel.text = @"31.6"
  50.  
  51. - (void) clearInfo { 
  52.     nameLabel.text = @""
  53.     ageLabel.text = @""
  54.  
  55. @end 

以上的代码重构,要遵守几个规则:

1)在createFields方法中接收从上一个页面传递过来的参数

2)在createFields方法中初始化变量

3)将要操作的控件,都在ViewController中作为类级别的变量来声明

3)在createViews方法中,加载xib文件,并通过Tag给控件一次性赋值

4)在createEvent方法中,为控件挂上事件方法,比如按钮的点击

5)如果有NotificationCenter,统一在createEvent方法中addObserver,在destroyEvent方法中removeObserver。

6)在DestroyFields方法中,释放/销毁所有引用型变量。

7)在DestroyViews方法中,释放/销毁所有控件。

所有的ViewController都这么写,整个App整齐划一。尤其是将一个页面的所有控件一次性都从xib中根据tag值取出来,虽然浪费了一些内存,但是可以随时随地直接使用。

将声明一个按钮和为按钮添加一个点击事件方案分开在2个方法内写,一开始你会非常不习惯,但是当控件多了、事件多了的时候,是一目了然的。记住,我们在做的是企业级App开发,而不是小型App。

看到最后,熟悉网站端编程的人笑了,没错,这种新的生命周期,就是从javascript中借鉴来的。js是一门弱语言,所以需要自定义生命周期并按部就班在不同的方法中写不同的方法,生命周期的重新定义,或者说是扩展,只是js代码框架中的一个小部分。

本章代码下载:

YoungHeart-Chapter-04-1.zip (重构前)

YoungHeart-Chapter-04-2.zip   (重构后)

责任编辑:闫佳明 来源: cnblogs
相关推荐

2013-09-09 10:48:24

iOS无线客户端框架设计

2013-09-03 09:35:48

无线客户端框架设计iOS

2013-09-03 09:55:42

iOS无线客户端框架设计

2013-09-16 10:43:15

无线客户端框架设计iOSJSON

2013-09-03 09:10:56

2012-06-01 11:02:33

2013-07-29 05:11:38

iOS开发iOS开发学习类的'生命周期'

2015-07-09 15:42:48

ios应用生命周期

2009-08-10 14:31:46

ASP.NET组件设计ASP.NET控件生命

2011-03-07 13:50:20

2013-12-18 11:38:56

京东客户生命周期大数据应用

2013-03-14 10:12:54

视觉设计产品设计

2015-07-08 16:28:23

weak生命周期

2012-06-25 12:43:26

.NET框架

2022-04-19 07:20:24

软件开发安全生命周期SSDLC应用安全

2023-03-31 13:31:45

2020-07-30 10:35:32

Java反射框架设计

2012-01-18 10:20:42

框架设计

2012-11-28 11:05:42

IBMdW

2011-03-21 09:45:52

Hello WorldObjective-C生命周期
点赞
收藏

51CTO技术栈公众号