iphone程序的生命周期分析

一、概述

做iphone开发,了解iphone程序的生命周期非常的重要。从点击程序图标启动程序开始,到退出程序,程序整个运行过程中都发生了什么事情?为什么要这么做?只有理解了这些技术细节才能游刃有余的掌握Iphone程序的开发。

二、目标

首先来写一个HelloWorld程序,放弃Xcode提供的代码模板,不使用xib不使用ib,不使用storyboard,亲自动手一行一行的编写代码。虽然真正开发项目的时候并不需要这样做,Xcode模板和ib/storyboard都做好这些事情,但是现在完全由自己来写,可以详细了解整个启动的过程和机制。

三、协议介绍

先来看看object-c语言的关于协议的代码片段:

// 定义一个协议

@protocol SimpleProtocol

-(void)doSomething:(NSString *)str;   //定义一个方法

@end

//定义一个接口,使用了上面定义的协议

@interface SimpleClass:NSObject  <SimpleProtocol> {

}

@end

//接口实现类

@implementation SimpleClass

-(void) doSomething:(NSString *)str{ 

   NSLog(str);

}

@end


这样是一个简单的协议示例,类SimpleClasss实现了名为SimpleProtocol的协议。协议在其它语言里跟接口非常类似,记住这个协议的实现,接下来会有用的。


四、用xcode生成一个HelloWorld项目

用Xcode新建一个名为HelloWorld的Single view Application类型的项目。

大体上讲一下项目的文件结构,由Xcode模板生成的项目主要包含

Classes(HelloWorldAppdelegate.h和HelloWorldAppDelegate.m)、

Other Sources(Xcode 4.5是 Supporting Files目录)(main.m和HelloWorld_Prefix.pch)、

Resources(MainWindow.xib和HelloWorld-info.plist)、

Frameworks(iphoneSDK提供的系统框架)、

Products(HelloWorld.app)这几部分。

直接运行这个工程会在模拟器里看到一个白色的显示界面程序,由此可见没写一行代码Xcode已经生成了一个很简单的、可运行的项目模板。


五、分析

每一个iphone程序都包含一个UIApplication对象,它管理整个程序的生命周期,从加载第一个显示界面开始,并且监听系统事件、程序事件调度整个程序的执行。那么上面这个简单项目中的UIApplication对象在哪呢?在这个项目中我们找不到任何关于UIApplication的代码,其实在项目中UIApplication对象是由UIApplicationMain方法初始化到内存中,首先打开Other Sources(Xcode 4.5是Supporting Files)文件夹下的main.m源文件,里面只包括了一个main方法,和所有的C程序一样这个是程序入口。代码如下:

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

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

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

    [pool release];

    return retVal;

}


在main函数中第二行代码UIApplicationMain(argc, argv, nil, nil)对UIApplication对象进行了初始化,函数原形


int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);


这个函数除了argc 和 argv 参数外,还有2个两个字符串参数来识别 UIApplication 类和 UIApplication 代理类。

当第一个参数为nil时,就默认把 UIApplication 类作为缺省值进行初始化,这里可以不填nil,而是使用自己定义的UIApplication子类。

第二个参数为nil,l就把模板生成的 HelloWorldAppDelegate 类作为默认值。

这里有了 UIApplicationMain 对象怎么又出来一个UIApplication代理类对象呢?需要说明的是 UIApplication对象的作用是管理整个程序的生命周期,实际上它是什么具体的事情都不干,只是负责监听事件。当需要做实际工作的时候就交给UIApplication代理类(即HelloWorldAppDelegate)去做,UIApplication负责把命令传达给UIApplication代理类HelloWorldAppDelegate,然后由HelloWorldAppDelegate去处理,这就是代理模式。


六、处理

现在开始手工编写第一个iphone程序helloWorld。

上面说过,要放弃使用代码模板,放弃xib和ib以及storyboard,现在把Xcode模板自动生成的代码部分删除。

操作如下:

1、把Other Sources(Xcode 4.5Supporting Files)文件下main.m删除;

2、把Classes(Xcode 4.5是HelloWork)文件夹下的HelloWorldAppDelegate.h和HelloWorldAppDelegate.m删除;

3、把Resources文件夹下的MainWindow.xib删除(在Xcode4.5中是HelloWorld目录下的MainStoryboard.storyboard);

4、打开Resources文件夹下HelloWorld-info.plist,然后找到key为“Main nib file base name”删除,因为在上面已经删除了MainWindow.xib;

这样就完成的工程的清理,变成了一个真正的空的工程没有什么实现代码。


七、改造


完成上面的处理工作后,接下来开始的编写。

首先新建程序入口main.m文件以及main方法,程序从这里开始!!!

代码如下:

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

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

    int retVal = UIApplicationMain(argc, argv, nil, @”SampleDelegate”);

    [pool release];

    return retVal;

}    


第二行UIApplicationMain(argc, argv, nil, nil) 与模板生成的相比改成UIApplicationMain(argc, argv, nil, @”SampleDelegate”);

这样就为UIApplication对象设置了名为SampleDelegate代理类,UIApplication是做具体事情,真正做事的是UIApplication代理类,即SampleDelegate。

这个名为SampleDelegate代理类就是我们需要具体写代码实现的,当UIApplication初始化后就开始监听事件,根据不同的监听事件让SampleDelegate代理类做不同的处理,比如显示第一个显示界面。


新建名为SampleDelegate.m的类,在SampleDelegate.h输入如下代码:

@interface SampleDelegate : NSObject<UIApplicationDelegate> {

}

@end


注意到没有,SampleDelegate: NSObject <UIApplicationDelegate>这个写法是不是很眼熟 ,在看看最上面那段object-c语言的关于协议代码,SimpleClass类需要实现SimpleProtocol协议定义的方法,这样看来UIApplicationDelegate是一个协议定义,同样SampleDelegate也需要实现UIApplicationDelegate中定义的方法,只是这个协议是系统定义好的(具体可以参看UIApplicationDelegate.h)而SimpleProtocol是我们自己定义的,但是要做的事情相同,就是SampleDelegate需要去实现这UIApplicationDelegate协议定义好的方法, 这些方法就是UIApplication对象监听到系统变化的时候通知UIApplication对象代理类SampleDelegate执行的相应方法。


下面是SampleDelegate的实现代码写在SampleDelegate.m中:

@implementation SampleDelegate

- (void)applicationWillResignActive:(UIApplication *)application{}

- (void)applicationDidBecomeActive:(UIApplication *)application{}

- (void)applicationDidEnterBackground:(UIApplication *)application{}

- (void)applicationWillEnterForeground:(UIApplication *)application{}

- (void)applicationWillTerminate:(UIApplication *)application{}

- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application{}

- (void)applicationSignificantTimeChange:(UIApplication*)application{}

- (void)applicationDidFinishLaunching:(UIApplication*)application{}

- (void)application:(UIApplication*)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame{}

- (void)application:(UIApplication*)application willChangeStatusBarOrientation:(UIInterfaceOrientation)newStatusBarOrientationduration:(NSTimeInterval)duration{}

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

         return YES;

}

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

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

@end


现在来看协议中定义的这些需要实现的方法分别是什么作用:

1、-(void)applicationWillResignActive:(UIApplication *)application

说明:当应用程序将要入非活动状态执行,在此期间,应用程序不接收消息或事件,比如来电话了

2、-(void)applicationDidBecomeActive:(UIApplication *)application

说明:当应用程序入活动状态执行,这个刚好跟上面那个方法相反

3、- (void)applicationDidEnterBackground:(UIApplication*)application

说明:当程序被推送到后台的时候调用。所以要设置后台继续运行,则在这个函数里面设置即可

4、-(void)applicationWillEnterForeground:(UIApplication *)application

说明:当程序从后台将要重新回到前台时候调用,这个刚好跟上面的那个方法相反。

5、-(void)applicationWillTerminate:(UIApplication *)application

说明:当程序将要退出是被调用,通常是用来保存数据和一些退出前的清理工作。这个需要要设置UIApplicationExitsOnSuspend的键值。

6、-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application

说明:iPhone设备只有有限的内存,如果为应用程序分配了太多内存操作系统会终止应用程序的运行,在终止前会执行这个方法,通常可以在这里进行内存清理工作防止程序被终止

7、-(void)applicationSignificantTimeChange:(UIApplication*)application

说明:当系统时间发生改变时执行

8、-(void)applicationDidFinishLaunching:(UIApplication*)application

说明:当程序载入后执行

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

说明:当StatusBar框将要变化时执行

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

(UIInterfaceOrientation)newStatusBarOrientation

duration:(NSTimeInterval)duration

说明:当StatusBar框方向将要变化时执行

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

说明:当通过url执行

12、-(void)application:(UIApplication*)applicationdidChangeStatusBarOrientation:(UIInterfaceOrientation)oldStatusBarOrientation

说明:当StatusBar框方向变化完成后执行

13、-(void)application:(UIApplication*)applicationdidChangeSetStatusBarFrame:(CGRect)oldStatusBarFrame

说明:当StatusBar框变化完成后执行


下图是一个大概流程图,不是很准确但是基本上也说明了整个过程,仅供参考:



到这为止我们的这个程序运行起来还是什么都没有看到,确实我们也没有写具体的功能代码,接下来我们要做的就是在屏幕上显示“Hello World!”,首先知道一下要在屏幕上显示,首先需要一个UIWindow对象,这个你可以认为是一个电视机,然后还需要往这个UIWindow对象里添加UIView对象,UIView相当于电视上一幕一幕的画面。通过上面的流程知道要在程序后显示可以在applicationDidFinishLaunching方法中处理,这样修改applicationDidFinishLaunching方法如下:

- (void)applicationDidFinishLaunching:(UIApplication*)application{

         UIWindow *window=[[UIWindow alloc]initWithFrame:[[UIScreen mainScreen] bounds]];

         SampleViewController *viewctrl=[[SampleViewController alloc]init];

         [windowaddSubview:viewctrl.view];

         [windowmakeKeyAndVisible];

}

上面的代码中做了如下几件事情:

1、 实例化了一个UIWindow对象

2、 实例化了SampleViewController对象

3、 把SampleViewController对象UIView对象添加到UIWindow对象中

4、 显示UIWindow对象

看这段代码我们并没有直接实例化一个UIView对象然后添加给UIWindow对象而且通过SampleViewController对象,它是UIViewController子类负责视图的显示控制,非常的好用,在这里我们只是实现了loadView就够了,我们只要简单的显示一下“Hello World!”文字, 具体代码如下:

@interface SampleViewController : UIViewController {}

@end

@implementation SampleViewController

-(void)loadView{

         UIView *contentView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]];

         contentView.backgroundColor = [UIColor blackColor];

         self.view = contentView;

         [contentView release];

         CGRect labelFrame = CGRectMake(40.0f, 200.0f, 240.0f, 60.0f);

         UILabel *frontLabel = [[UILabel alloc] initWithFrame:labelFrame];

         frontLabel.text = @"Hello World!";

         frontLabel.font = [UIFont fontWithName:@"Georgia" size:24.0f];

         frontLabel.textColor = [UIColor colorWithRed:0.82f green:1.0f blue:0.286f alpha:1.0f];

         frontLabel.backgroundColor = [UIColor colorWithRed:0.0f green:0.0f blue:0.0f alpha:0.0f];

         [contentViewaddSubview:frontLabel];

         [frontLabelrelease];    

}

@end

到这里我们已经完成的HelloWorld程序的编写,点击运行就能看到如下的效果图:



参考文章: http://hi.baidu.com/892638548/item/6c015314c8fb34592b3e2237


你可能感兴趣的:(xcode,xcode,xcode,iPhone,iPhone,iPhone,iPhone,iPhone)