iOS开发UI篇之16程序启动原理和UIApplication

iOS 开发 UI   程序启动原理和 UIApplication

一、 UIApplication

1. 简单介绍

( 1 ) UIApplication 对象是应用程序的象征,一个 UIApplication 对象就代表一个应用程序。

( 2 )每一个应用都有自己的 UIApplication 对象,而且是单例的,如果试图在程序中新建一个 UIApplication 对象,那么将报错提示。

( 3 )通过 [UIApplicationsharedApplication] 可以获得这个单例对象

( 4 )   一个 iOS 程序启动后创建的第一个对象就是 UIApplication 对象,且只有一个(通过代码获取两个 UIApplication 对象,打印地址可以看出地址是相同的)。

( 5 )利用 UIApplication 对象,能进行一些应用级别的操作

2. 应用级别的操作示例:

1 )设置应用程序图标右上角的红色提醒数字(如 QQ 消息的时候,图标上面会显示 1 , 2 , 3 条新信息等。)

@property(nonatomic) NSInteger applicationIconBadgeNumber;

代码实现和效果:  

- ( IBAction )changeAppNum {

//错误,只能有一个唯一的UIApplication对象,不能再进行创建

//    UIApplication*app=[[UIApplication alloc]init];

UIApplication *app = [ UIApplication sharedApplication ];

// 0代表清除图标右上角的数字

app. applicationIconBadgeNumber = 20 ;

}

2 )设置联网指示器的可见性

@property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;

代码和效果 : 

//设置指示器的联网动画

app. networkActivityIndicatorVisible = YES ;

3 )管理状态栏

从 iOS7 开始,系统提供了 2 种管理状态栏的方式

a. 通过 UIViewController 管理(每一个 UIViewController 都可以拥有自己不同的状态栏) .

在 iOS7 中,默认情况下,状态栏都是由 UIViewController 管理的, UIViewController 实现下列方法就可以轻松管理状态栏的可见性和样式

状态栏的样式   -(UIStatusBarStyle)preferredStatusBarStyle; 

状态栏的可见性 -(BOOL)prefersStatusBarHidden;

#pragma mark-设置状态栏的样式

-(UIStatusBarStyle)preferredStatusBarStyle

{

//设置为白色

//return UIStatusBarStyleLightContent;

//默认为黑色

return UIStatusBarStyleDefault;

}

#pragma mark-设置状态栏是否隐藏(否)

-( BOOL )prefersStatusBarHidden

{

return NO ;

}

}

b. 通过 UIApplication 管理(一个应用程序的状态栏都由它统一管理)

如果想利用 UIApplication 来管理状态栏,首先得修改 Info.plist 的设置

代码:

UIApplication *app=[UIApplication sharedApplication];

app. applicationIconBadgeNumber = 123 ;

//设置指示器的联网动画

app. networkActivityIndicatorVisible = YES ;

//设置状态栏的样式

//app.statusBarStyle=UIStatusBarStyleDefault;//默认(黑色)

//设置为白色+动画效果

[app setStatusBarStyle : UIStatusBarStyleLightContent animated : YES ];

//设置状态栏是否隐藏

app. statusBarHidden = YES ;

//设置状态栏是否隐藏+动画效果

[app setStatusBarHidden : YES withAnimation : UIStatusBarAnimationFade ];

c. 补充

既然两种都可以对状态栏进行管理,那么什么时候该用什么呢?

如果状态栏的样式只设置一次,那就用 UIApplication 来进行管理;

如果状态栏是否隐藏,样式不一样那就用控制器进行管理。

UIApplication 来进行管理有额外的好处,可以提供动画效果。

4 ) openURL: 方法

UIApplication 有个功能十分强大的 openURL: 方法

- (BOOL)openURL:(NSURL*)url;

openURL: 方法的部分功能有

打电话  UIApplication *app =[UIApplicationsharedApplication]; [appopenURL:[NSURLURLWithString:@"tel://10086"]];

发短信  [app openURL:[NSURLURLWithString:@"sms://10086"]];

发邮件  [appopenURL:[NSURLURLWithString:@"mailto://12345@qq.com"]];

打开一个网页资源  [appopenURL:[NSURLURLWithString:@"http://ios.itcast.cn"]];

打开其他 app 程序   openURL 方法,可以打开其他 APP 。

URL 补充 :

URL :统一资源定位符,用来唯一的表示一个资源。

URL 格式 : 协议头: // 主机地址 / 资源路径

网络资源: http/ftp 等   表示百度上一张图片的地址   http://www.baidu.com/images/20140603/abc.png

本地资源: file:///users/apple/desktop/abc.png( 主机地址省略 )

二、 UIApplication Delegate

1. 简单说明

所有的移动操作系统都有个致命的缺点: app 很容易受到打扰。比如一个来电或者锁屏会导致 app 进入后台甚至被终止。

还有很多其它类似的情况会导致 app 受到干扰,在 app 受到干扰时,会产生一些系统事件,这时 UIApplication 会通知它的 delegate 对象,让 delegate 代理来处理这些系统事件。

作用:当被打断的时候,通知代理进入到后台。

每次新建完项目,都有个带有 “AppDelegate” 字眼的类,它就是 UIApplication 的代理 ,NJAppDelegate 默认已经遵守了 UIApplicationDelegate 协议,已经是 UIApplication 的代理。

2. 代理方法

/**

*  app启动完毕后就会调用

*/

- ( BOOL )application:( UIApplication *)application didFinishLaunchingWithOptions:( NSDictionary *)launchOptions

{

NSLog ( @"%@" , self . window );

NSLog ( @"didFinishLaunchingWithOptions" );

// Override point for customizationafter application launch.

return YES ;

}

- ( void )applicationWillResignActive:( UIApplication *)application

{

}

/**

*  app进入后台的时候调用

*

* 一般在这里保存应用的数据(游戏数据,比如暂停游戏)

*/

- ( void )applicationDidEnterBackground:( UIApplication *)application

{

NSLog ( @"applicationDidEnterBackground" );

}

- ( void )applicationWillEnterForeground:( UIApplication *)application

{

NSLog ( @"applicationWillEnterForeground" );

.

}

- ( void )applicationDidBecomeActive:( UIApplication *)application

{

}

/**

*  清除不需要再使用的内存

*/

- ( void )applicationDidReceiveMemoryWarning:( UIApplication *)application

{

NSLog ( @"applicationDidReceiveMemoryWarning" );

}

- ( void )applicationWillTerminate:( UIApplication *)application

{

}

@end

应用程序一般有五个状态:官方文档 app.states

三、程序启动原理

UIApplicationMain

main 函数中执行了一个 UIApplicationMain 这个函数

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

argc 、 argv :直接传递给 UIApplicationMain 进行相关处理即可  

principalClassName :指定应用程序类名( app 的象征),该类必须是 UIApplication( 或子类 ) 。如果为 nil, 则用 UIApplication 类作为默认值

delegateClassName :指定应用程序的代理类,该类必须遵守 UIApplicationDelegate 协议

UIApplicationMain 函数会根据 principalClassName 创建 UIApplication 对象,根据delegateClassName 创建一个 delegate 对象,并将该 delegate 对象赋值给 UIApplication 对象中的 delegate 属性

接着会建立应用程序的 Main Runloop (事件循环),进行事件的处理 ( 首先会在程序完毕后调用 delegate 对象的 application:didFinishLaunchingWithOptions: 方法 )

程序正常退出时 UIApplicationMain 函数才返回

#import <UIKit/UIKit.h>

#import "TXAppDelegate.h"

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

{

@autoreleasepool {

// return UIApplicationMain(argc, argv,nil, NSStringFromClass([TXAppDelegate class]));

@autoreleasepool {

//        returnUIApplicationMain(argc, argv, nil, @"MJAppDelegate");

//        returnUIApplicationMain(argc, argv, @"UIApplication",@"MJAppDelegate");

// return UIApplicationMain(argc, argv,nil, NSStringFromClass([YYAppDelegate class]));

// return UIApplicationMain(argc, argv,@"UIApplication", NSStringFromClass([YYAppDelegate class]));

/*

argc: 系统或者用户传入的参数个数

argv: 系统或者用户传入的实际参数

1.根据传入的第三个参数创建UIApplication对象

2.根据传入的第四个产生创建UIApplication对象的代理

3.设置刚刚创建出来的代理对象为UIApplication的代理

4.开启一个事件循环

*/

return UIApplicationMain (argc, argv, NSStringFromClass ([ UIApplication class ]), NSStringFromClass ([ TXAppDelegate class ]));

}

}

系统入口的代码和参数说明:

argc: 系统或者用户传入的参数

argv: 系统或用户传入的实际参数  

1. 根据传入的第三个参数,创建 UIApplication 对象

2. 根据传入的第四个产生创建 UIApplication 对象的代理

3. 设置刚刚创建出来的代理对象为 UIApplication 的代理

4. 开启一个事件循环(可以理解为里面是一个死循环)这个时间循环是一个队列(先进先出)先添加进去的先处理

ios 程序启动原理

四、程序启动的完整过程

1.main 函数

2.UIApplicationMain

* 创建 UIApplication 对象

* 创建 UIApplication 的 delegate 对象

3.delegate 对象开始处理 ( 监听 ) 系统事件 ( 没有 storyboard)

* 程序启动完毕的时候 , 就会调用代理的 application:didFinishLaunchingWithOptions: 方法

* 在 application:didFinishLaunchingWithOptions: 中创建 UIWindow

* 创建和设置 UIWindow 的 rootViewController

* 显示窗口

3. 根据 Info.plist 获得最主要 storyboard 的文件名 , 加载最主要的 storyboard( 有 storyboard)

* 创建 UIWindow

* 创建和设置 UIWindow 的 rootViewController

* 显示窗口

原文地址:https://www.cnblogs.com/iosblogx/p/4474175.html