p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Heiti SC Light'} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px 'Courier New'} span.s1 {font: 14.0px 'Lucida Grande'} span.s2 {font: 15.0px Courier; color: #666666} span.s3 {font: 15.0px Courier; color: #0100a9} span.s4 {color: #0100a9} span.s5 {font: 14.0px 'Heiti SC Light'} span.s6 {font: 11.0px 'Courier New'} span.s7 {font: 14.0px 'Lucida Grande'; color: #0100a9}
iphone和windows编程还是有些差别,总是容易忘记,还是写下来,免得以后总要回头查一遍。
在iPhone的应用程序中,main函数仅在最小程度上被使用,应用程序运行所 需的大多数实际工作由UIApplicationMain函数来处理。因此,当您在 Xcode中开始一个新的应用程序工程时,每个工程模板都会提供一个main函 数的标准实现,该实现和“处理关键的应用程序任务”部分提供的实现是一样 的 。main例 程 只 做 三 件 事 : 创 建 一 个 自 动 释 放 池 , 调 用 UIApplicationMain函数,以及使用自动释放池。除了少数的例外,您永 远不应该改变这个函数的实现。
程序清单1-1 iPhone应用程序的main函数 #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;请注意:自动释放池用于内存管理,它是Cocoa的一种机制,用于延缓释放具 有一定功能的代码块中创建的对象。有关自动释放池的更多信息,请参见 Cocoa内存管理编程指南;如果需要了解与自动释放池有关的具体内存管理规 则,则请参见“恰当地分配内存”部分。 程序清单的核心代码是UIApplicationMain函数,它接收四个参数,并将 它们用于初始化应用程序。传递给该函数的缺省值并不需要修改,但是它们对 于应用程序启动的作用还是值得解释一下。除了传给main函数的argc和 argv之外,该函数还需要两个字符串参数,用于标识应用程序的首要类(即 应用程序对象所属的类)和应用程序委托类。如果首要类字符串的值为nil, UIKit就缺省使用UIApplication类;如果应用程序委托类为nil,UIKit就 会将应用程序主nib文件(针对通过Xcode模板创建的应用程序)中的某个对 象假定为应用程序的委托对象。如果您将这些参数设置为非nil值,则在应用 程序启动时,UIApplicationMain函数会创建一个与传入值相对应的类实 例,并将它用于既定的目的。因此,如果您的应用程序使用了 UIApplication类的定制子类(这种做法是不推荐的,但确实是可能的), 就需要在第三个参数指定该定制类的类名。
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px 'Heiti SC Light'} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Heiti SC Light'} span.s1 {color: #0100a9} span.s2 {font: 14.0px 'Lucida Grande'} span.s3 {font: 15.0px Courier; color: #666666}
应用程序的委托
监控应用程序的高级行为是应用程序委托对象的责任,而应用程序委托对象是 您提供的定制类实例。委托是一种避免对复杂的UIKit对象(比如缺省的 UIApplication对象)进行子类化的机制。在这种机制下,您可以不进行子 类化和方法重载,而是将自己的定制代码放到委托对象中,从而避免对复杂对 象进行修改。当您感兴趣的事件发生时,复杂对象会将消息发送给您定制的委 托对象。您可以通过这种“挂钩”执行自己的定制代码,实现需要的行为。
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Heiti SC Light'} span.s1 {font: 14.0px 'Lucida Grande'} span.s2 {font: 14.0px 'Lucida Grande'; color: #0100a9} span.s3 {color: #0100a9} span.s4 {font: 15.0px Courier; color: #0100a9} span.s5 {font: 15.0px Courier; color: #666666}
重要提示:委托模式的目的是使您在创建应用程序的时候省时省力,因此是非 常重要的设计模式。如果您需要概要了解iPhone应用程序中使用的重要设计模 式,请参见“基本设计模式”部分;如果需要对委托和其它UIKit设计模式的详细 描述,则请参见Cocoa基本原理指南部分。
应用程序的委托对象负责处理几个关键的系统消息。每个iPhone应用程序都必 须有应用程序委托对象,它可以是您希望的任何类的实例,但需要遵循 UIApplicationDelegate协议,该协议的方法定义了应用程序生命周期 中的某些挂钩,您可以通过这些方法来实现定制的行为。虽然您不需要实现所 有的方法,但是每个应用程序委托都应该实现“处理关键的应用程序任务”部分 中描述的方法。
有 关UIApplicationDelegate协 议 方 法 的 更 多 信 息 请 参 见 UIApplicationDelegate协议参考。
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 18.0px 'Heiti SC Light'} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 14.0px 'Heiti SC Light'} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 21.0px 'Heiti SC Light'} span.s1 {font: 18.0px 'Lucida Grande'} span.s2 {font: 14.0px 'Lucida Grande'; color: #0100a9} span.s3 {color: #0100a9} span.s4 {font: 14.0px 'Lucida Grande'} span.s5 {font: 15.0px Courier; color: #666666} span.Apple-tab-span {white-space:pre}
主Nib文件
初始化的另一个任务是装载应用程序的主nib文件。如果应用程序的信息属性 列表(Info.plist)文件中含有NSMainNibFile键,则作为初始化过程的 一个部分,UIApplication对象会装载该键指定的nib文件。主nib文件是 唯一一个自动装载的nib文件,其它的nib文件可以在稍后根据需要进行装载。
Nib文件是基于磁盘的资源文件,用于存储一或多个对象的快照。iPhone应用 程序的主nib文件通常包含一个窗口对象和一个应用程序委托对象,还可能包 含一个或多个管理窗口的其它重要对象。装载一个nib文件会使该文件中的对 象被重新构造,从而将每个对象的磁盘表示转化为应用程序可以操作的内存对 象。从nib文件中装载的对象和通过编程方式创建的对象之间没有区别。然 而,对于用户界面而言,以图形的方式(使用Interface Builder程序)创建与 用户界面相关联的对象并将它们存储在nib文件中通常比以编程的方式进行创 建更加方便。
有关nib文件及其在iPhone应用程序中如何使用的更多信息,请参见“Nib文 件”部分,有关如何为应用程序指定主nib文件的信息则请参见“信息属性列 表”部分。
事件处理周期
在应用程序初始化之后,UIApplicationMain函数就会启动管理应用程序 事件和描画周期的基础组件,如图1-2所示。在用户和设备进行交互的时候, iPhone OS会检测触摸事件,并将事件放入应用程序的事件队列。然后, UIApplication对象的事件处理设施会从队列的上部逐个取出事件,将它分 发到最适合对其进行处理的对象。举例来说,在一个按键上发生的触摸事件会 被分发到对应的按键对象。事件也可以被分发给控制器对象和应用程序中不直 接负责处理触摸事件的其它对象。