详解iPhone委托模式兼谈iPhone生命周期

时间:2011-08-26

 

  iPhone由苹果公司(Apple, Inc.)执行官史蒂夫·乔布斯在2007年1月9日举行的Macworld宣布推出,2007年6月29日在美国上市,将创新的移动电话、可触摸宽屏iPod以及具有桌面级电子邮件、网页浏览、搜索和地图功能的突破性因特网通信设备这三种产品完美地融为一体。iPhone引入了基于大型多触点显示屏和性新软件的全新用户界面,让用户用手指即可控制iPhone.iPhone还开创了移动设备软件功能的新纪元,重新定义了移动电话的功能。现在中国大陆iPhone使用率已经非常高了,在各个时尚潮人,明星,高层之中普及率更高。它被定义为一种高品味的象征。很多网站,实体店等等有有iPhone配件以及整机出售,为中国的通讯产业的发展做出了巨大的贡献。同时也解决了不少人的就业问题。iPhone无疑是非常伟大的跨时代产品,甚至有人打出"无所不能的iPhone"这样的口号。至今仍没有一款手机可以在用户体验上超越iphone!目前在APP store上的软件已经达到几十万,累计量超亿次。

  每个iPhone应用程序都有一个UIApplication,UIApplication是iPhone应用程序的开始并且负责初始化并显示UIWindow,并负责加载应用程序的个UIView到UIWindow窗体中。UIApplication的另一个任务是帮助管理应用程序的生命周期,而UIApplication通过一个名字为UIApplicationDelegate的代理类来履行这个任务。尽管UIApplication会负责接收事件,而UIApplicationDelegate则决定应用程序如何去响应这些事件,UIApplicationDelegate可以处理的事件包括应用程序的生命周期事件(比如程序启动和关闭)、系统事件(比如来电、记事项警告),本文会介绍如何加载应用程序的UIView到UIWindow以及如何利用UIApplicationDelegate处理系统事件。

  通常对于UIApplication读者是没必要修改它的,只需要知道UIApplication接收系统事件即可,而如何编写代码来处理这些系统事件则是程序员的工作。处理系统事件需要编写一个继承自UIApplicationDelegate接口的类,而UIApplicationDelegate接口提供生命周期函数来处理应用程序以及应用程序的系统事件,这些生命周期函数如下表所示:

UIApplicationDelegate Event-Handling Methods

Method Signature

1:application:didChangeStatusBarFrame:

- (void)application:(UIApplication*)application didChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame

2:application:didChangeStatusBarOrientation:

- (void)application:(UIApplication*)application didChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation

3:application:handleOpenURL:

- (BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url

4:application:willChangeStatusBarOrientation:duration:

- (void)application:(UIApplication*)application willChangeStatusBarOrientation:

(UIInterfaceOrientation)newStatusBarOrientation
duration:(NSTimeInterval)duration

5:application:willChangeStatusBarFrame

- (void)application:(UIApplication)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame

6:applicationDidBecomeActive:

- (void)applicationDidBecomeActive:(UIApplication*)application

7:applicationDidFinishLaunching:

- (void)applicationDidFinishLaunching:(UIApplication*)application

8:applicationDidReceiveMemoryWarning:

- (void)applicationDidReceiveMemoryWarning:(UIApplication*)application

9:applicationSignificantTimeChange:

- (void)applicationSignificantTimeChange:(UIApplication*)application

10:applicationWillResignActive:

- (void)applicationWillResignActive:(UIApplication*)application

11:applicationWillTerminate:

- (void)applicationWillTerminate:(UIApplication*)application

 

1

  如果利用Xcode的模板创建项目,Xcode会为程序员创建继承自UIApplicationDelegate的类,但不会自动实现继承自UIApplicationDelegate的可选的事件处理函数。如果读者创建一个名为"TestUIApplication"的项目,Xcode会自动创建TestUIApplicationAppDelegate.h和TestUIApplicationAppDelegate.m文件,文件的声明如下:

  @interface TestUIApplicationAppDelegate : NSObject 《UIApplicationDelegate》

  而应用程序的UIApplication则被定义在MainWindow.xib文件中,并且有一个作为outlet的UIApplicationDelegate引用,如下图:

  

  图1

  当应用程序接收到表1中的事件时,UIApplication会调用UIApplicationDelegate中实现的相应的方法。

  从根本上讲,委托(delegate)是iPhone中广泛采用的一种编程方法,这种方法有很多益处:

  它更为简洁的把程序的逻辑处理从UIApplication中分离了出来。

  它避免了程序员直接从UIApplication派生子类,试想如果通过从UIApplication派生子类的方法来管理应用程序的生命周期和系统事件是多么痛苦的一件事情。

  同样,"委托模式"也是一种常用的面向对象的设计模式,这种设计模式用Java语言可以更好的进行描述。

  "委托模式"中一般有两个对象参与处理同一个请求,所谓的请求在iPhone中就是应用程序的生命周期和系统事件,接受请求的对象将请求委托给另一个对象来处理,同样在iPhone中对应的是UIApplication在接收到生命周期和系统事件后委托给UIApplicationDelegate来处理。同样,委托模式也是很多其它模式的基础,如状态模式、策略模式、访问者模式本质上是在特殊的情况下采用了委托模式。委托模式使得可以用聚合代理继承,正如iPhone中为了避免直接从UIApplication继承而采用委托模式一样。

  Java平台由Java虚拟机(Java Virtual Machine)和Java 应用编程接口(Application Programming Interface、简称API)构成。Java 应用编程接口为Java应用提供了一个独立于操作系统的标准接口,可分为基本部分和扩展部分。在硬件或操作系统平台上安装一个Java平台之后,Java应用程序就可运行。现在Java平台已经嵌入了几乎所有的操作系统。这样Java程序可以只编译,就可以在各种系统中运行。Java应用编程接口已经从1.1x版发展到1.2版。目前常用的Java平台基于Java1.5,近版本为Java1.7.Java分为三个体系JavaSE(Java2 Platform Standard Edition,java平台标准版),JavaEE(Java 2 Platform,Enterprise Edition,java平台企业版),JavaME(Java 2 Platform Micro Edition,java平台微型版)。

  如果用Java来模拟iPhone中委托模式的处理过程,UIApplication定义大致如下:

  public class UIApplication {

  public final int UP = 1;

  public final int DOWN = 2;

  public final int DRAG = 3;

  public final int DROP = 4;

  private UIApplicationDelegate Delegate;

  /**

  * @param args

  */

  public UIApplication(UIApplicationDelegate aDelegate)

  {}

  public boolean HandlerSysEvents(int aEventValue)

  {

  switch(aEventValue)

  {

  case UP:

  Delegate.HanlderEvents(aEventValue);

  break;

  case DOWN:

  Delegate.HanlderEvents(aEventValue);

  break;

  case DRAG:

  Delegate.HanlderEvents(aEventValue);

  break;

  case DROP:

  Delegate.HanlderEvents(aEventValue);

  break;

  }

  return false;

  }

  }

  而委托接口UIApplicationDelegate的定义如下:

  public interface UIApplicationDelegate {

  public void applicationDidFinishLaunching(UIApplication application);

  public boolean HanlderEvents(int aEventsValue);

  }

  可见,通过传递UIApplicationDelegate到UIApplication中,系统就可以在UIApplication接收到系统事件时调用委托类UIApplicationDelegate中相应的方法来处理系统事件。

  探究iPhone不采用继承体系而采用委托模式来实现聚合的原因,其更深层次在于iPhone框架的多样化使得继承无法保证子类行为的一致性,而委托模式恰恰是为了弥补继承的这个缺点诞生的。

  打开Other Sources目录下main.m文件,可以看到如下代码:

  #import 《UIKit/UIKit.h》

  int main(int argc, char *argv[]) {

  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

  int retVal = UIApplicationMain(argc, argv, nil, nil);

  [pool release];

  return retVal;

  }

  每个项目都会有一个UIApplication对象来处理应用程序的生命周期和系统事件,main()函数通过UIApplicationMain()来初始化应用程序的UIApplication,如果读者想对应用程序的UIApplication进行操作,就只能通过[UIApplication sharedApplication]来获取到UIApplication的引用,这个方法会返回一个全局的UIApplication对象给读者。

  该UIApplication类提供了一个内部监督办公室的协调运行的应用程序的集中控制点。每个应用程序必须有且只有一个实例UIApplication (或子类UIApplication )。当应用程序启动时, UIApplicationMain函数被调用;除其他任务,该函数创建一个单UIApplication对象。此后,您可以访问这个对象调用由sharedApplication类的方法。一个重要的角色UIApplication的目的是处理事件的初期路由传入的用户。这还调度对象(行动控制消息转发给它UIControl )到适当的目标对象。此外, UIApplication对象维护一个窗口列出所有的( UIWindow对象)当前打开的应用程序,因此它可以通过这些检索的任何应用程序UIView对象。应用程序对象通常被分配一个代表,一个对象,应用程序运行时事件通知重要,例如,应用程序启动,低内存警告,和应用程序终止,给它一个机会,作出适当的反应。应用程序可以通过一个协同处理资源,如电子邮件的图像文件或openURL:方法。

  同样,读者可以通过如下代码获取应用程序的委托对象:

  UIApplicationDelegate* myDelegate = [[UIApplication sharedApplication] delegate];

  在UIApplication接收到系统事件和生命周期事件时,会把相应的事件传递给UIApplicationDelegate进行处理,表1所列的生命周期函数大都是可选的,但为了应用程序的健壮性程序员应该实现它们。

  iPhone并不是多任务的操作系统,所以应用程序很容易受到打扰,比如一个来电可能导致应用程序失去焦点,如果这个时候接听了电话,那么应用程序会自动终止运行。还有很多其它类似的事件会导致iPhone应用程序失去焦点,在应用程序失去焦点前会调用委托类的applicationWillResignActive()方法,而应用程序再次获取到焦点的时候会调用applicationDidBecomeActive()方法。比如在运行应用程序的时候锁屏会调用委托类的applicationWillResignActive()方法,而当屏幕被解锁的时候,又会调用applicationDidBecomeActive()方法。

  另外一个非常重要的方法就是applicationDidReceiveMemoryWarning(),因为iPhone设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,但在终止之前操作系统会通过先调用委托类的applicationDidReceiveMemoryWarning()方法警告应用程序,在UIApplication接收到这个事件后它会传递给委托类的applicationDidReceiveMemoryWarning()方法,委托类在这个方法内可以进行释放内存的操作以防止操作系统强制终止应用程序的运行。

 


  
上一篇:浅谈RFID读写器抗冲突研究应用
下一篇:解析“3Geye”移动视频监控的详细方案

免责声明: 凡注明来源本网的所有作品,均为本网合法拥有版权或有权使用的作品,欢迎转载,注明出处。非本网作品均来自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

相关技术资料