zoukankan      html  css  js  c++  java
  • 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

    * 显示窗口

  • 相关阅读:
    server.c:5170:31: error: ‘struct redisServer'
    SpringBoot配置文件笔记:yaml语法,yaml如何写、注入配置文件类(2种方式根据业务场景选择)、多环境切换、配置文件加载优先级、指定位置加载配置文件
    微服务(Microservices)—— Martin Flower
    利用原生子窗体解决悬浮窗口播放的问题及踩坑记录
    uniapp中nvue页面如何使用iconfont字体图标
    项目经验踩坑记录:跨平台业务影响时注意要考虑多个平台
    SQL基础知识笔记:概述(层状/网状/关系模型)、数据类型、操作数据库能力(DDL/DML/DQL)、关系模型(主键、联合主键、外键、外键约束-性能影响、一对一、一对多、多对多、索引、索引效率)、实用SQL语句、事务(四个特性、四种隔离级别)
    Java的Maven基础知识笔记:Maven是什么、maven目录、pom.xml唯一ID、maven解决依赖管理、maven中央仓库与镜像、构建流程(声明周期、阶段、目标)、使用插件、模块管理、mvnw指定版本、如何发布自己的开源库
    Java里的IO基础知识笔记:IO流、字节流/字符流、File对象读取、输入流/输出流(使用过后及时关闭、缓冲区)、Filter模式、ZIP操作、读取classpath资源的意义、序列化/反序列化、Reader/Writer、使用Files工具类及其局限性
    推荐了解一个用于JavaScript的快速SQL数据库
  • 原文地址:https://www.cnblogs.com/iosblogx/p/4474175.html
Copyright © 2011-2022 走看看