iOS UIApplication详解(待更新)

UIApplication对象是应用程序的象征

  • 每一个应用都有自己的UIApplication对象,而且是单例的
  • 通过[UIApplication sharedApplication]可以获得这个单例对象,命名规范一般单例都是使用shared拿到
  • 一个iOS程序创建的第一个对象就是UIApplication对象
  • 利用UIApplication对象,能进行一些应用级别操作

什么是单例?

整个应用程序中只有一份,即只有一份内存,并不会分配多余的内存
新建项目,在ViewDidLoad中创建,会崩溃,原因为红色所圈部分


单例演示

苹果单例实现:

1.内部创建单例对象,程序启动的时创建该单例
2.提供一个方法,方便给外界获取单例对象
3.外界不能调用alloc方法,一调用就会崩溃,即抛异常

模仿UIApplication单例对象的实现,来更好的认识UIApplication

1.创建一个CrabMan,通过重写类方法load来模仿(类名随意)项目一启动就创建对象。load方法会在程序一启动时自动调用,将程序中所有的类加载出来,下图为验证效果图

+load方法讲解

2.创建并保存对象
创建完成后,使用静态全局变量来保存,并声明share方法供外部调用
疑问:为什么不用属性来保存?
解答:因为属性是属于对象的,在load方法对象还未创建完成,不能用对象的属性来保存该对象本身。

疑问:为什么只在.m文件中实现load方法?
解答:我们demo的目的是演示UIApplication的单例,对象的创建在内部进行,获取单例对象的方法提供给外部使用,该解答也回答了为什么shareCranMan方法需要在.h文件中声明。

对象的创建以及保存

3.重写系统alloc方法并抛异常
疑问:为什么return返回的是[super alloc]
解答:调用系统默认的方法,因为我们不知道分配内存的实现,又不想要覆盖原来方法的实现,所以就需要调用super alloc方法并将其返回

重新alloc方法

4.演示结果,外界调用alloc崩溃


结果演示

UIApplication的常用属性

  • 设置应用程序图标右上角的红色提醒数字
    @property(nonatomic) NSInteger applicationIconBadgeNumber;
badge
  • 设置联网指示器的可见性
    @property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL NetworkActivityIndicatorVisible;
    联网指示器
  • iOS 7 的状态栏
  • 打电话,发短信(需要真机)打开网页
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    UIApplication *application = [UIApplication sharedApplication];
    //1.获取应用程序图标的提醒数字
    /**
     设置后无效,查看属性下的英文注释:
     set to 0 to hide. default is 0. In iOS 8.0 and later, your application must register for user notifications using -[UIApplication registerUserNotificationSettings:] before
     */
    application.applicationIconBadgeNumber = 10;
    //创建通知对象
       UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
    //注册用户通知
    [application registerUserNotificationSettings:setting];
    
    //2.设置联网提示
    application.networkActivityIndicatorVisible = YES;
    
    
    //3.设置状态栏
    
    //application.statusBarHidden = YES;
    /**
     设置无效,查看官方注释
      Setting statusBarHidden does nothing if your application is using the default UIViewController-based status bar system.
     iOS7之后默认交给控制器管理状态栏
     */
   // - (BOOL)prefersStatusBarHidden NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED; // Defaults to NO
    // Override to return the type of animation that should be used for status bar changes for this view controller. This currently only affects changes to prefersStatusBarHidden.
    //配置info:添加key:View controller-based status bar appearance,并设置为NO,将状态栏的设置交给application来管理
    
    //方法已经过期
    [application setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
    
    
    //4.打电话 发信息 打开网页
    
    //打开网页:URL:资源的唯一标示;协议头+资源路径
    //原理:根据协议头判断用什么软件打开
    [application openURL:[NSURL URLWithString:@"http://www.baidu.com"]];    
}

UIApplication和delegate

  • 所有的移动操作系统都有个致命的缺点:app很容易受到打扰。比如一个来电或者是锁屏会导致app进入后台甚至终止。
  • 还有很多其他类似的情况都会导致app受到干扰,app受到干扰时,会产生一系列系统事件,这时UIApplication会通知他的delegate对象,让delegate来处理系统事件

delegate可处理的事件包括:

  • 应用程序的生命周期事件(如程序的启动和关闭)
  • 系统事件(如来电)
  • 内存警告
UIApplication和delegate

delegate方法讲解:

//应用程序启动完成后就会调用AppDelegate方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    return YES;
}
//当应用程序失去焦点的时候调用,只有当应用程序完全获取焦点的时候才能够与用户交互,所谓的获取焦点我的理解为app启动布满屏幕。
- (void)applicationWillResignActive:(UIApplication *)application {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
//当应用程序进入后台时候调用
- (void)applicationDidEnterBackground:(UIApplication *)application {
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
//当应用程序即将进入前台的时候调用
- (void)applicationWillEnterForeground:(UIApplication *)application {
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
//当应用程序获得焦点的时候调用
- (void)applicationDidBecomeActive:(UIApplication *)application {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
//当应用程序关闭的时候调用
- (void)applicationWillTerminate:(UIApplication *)application {
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end

各方法的调用时机的演示以及讲解
1.程序一启动未做任何操作
程序加载完毕,并获得焦点


程序启动

2.点击home键进入手机主界面
application先失去焦点然后 进入后台


程序进入后台

3.点击应用重新进入
application进入前台然后获得焦点


程序进入前台

4.双击home键关闭程序
程序关闭
关闭程序

由控制台打印结果可知按照上面的操作,先后顺序为:
程序加载完毕-->程序获得焦点-->程序失去焦点-->程序进入后台-->程序进入前台-->程序获得焦点-->程序关闭

程序的启动流程

讲解

演示main以及控制台打印结果

查看官方文档,了解参数的介绍
第三个参数:UIApplication类名或者子类的名称,如果传nil的话默认为@“UIApplication”
第四个参数:UIApplication的代理的类型名称,苹果使用NSStringFromClass([AppDelegate class])方法,获得对应类名,使用该方法除了可以避免输入错误的同时还具有提示功能。


官方文档

UIApplication底层实现原理:

1.根据principalClassName(第三个参数)传递的类名创建一个UIApplication对象
2.创建UIApplication代理对象,给UIApplication对象设置代理
3.开启主运行事件循环,处理事件,保持程序一直运行(后期runloop讲解)
4.加载Info.plist,判断application的Info.pist文件是否指定main,如果指定main就会记载nib文件

iOS程序的启动过程流程图

流程图
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,126评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,254评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,445评论 0 341
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,185评论 1 278
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,178评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,970评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,276评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,927评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,400评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,883评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,997评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,646评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,213评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,204评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,423评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,423评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,722评论 2 345

推荐阅读更多精彩内容

  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,124评论 29 470
  • 1.属性readwrite,readonly,assign,retain,copy,nonatomic 各是什么作...
    曾令伟阅读 1,044评论 0 10
  • *7月8日上午 N:Block :跟一个函数块差不多,会对里面所有的内容的引用计数+1,想要解决就用__block...
    炙冰阅读 2,473评论 1 14
  • 1,NSObject中description属性的意义,它可以重写吗?答案:每当 NSLog(@"")函数中出现 ...
    eightzg阅读 4,132评论 2 19
  • 一直都知道有一种家叫娘家,但未曾感受过。如今,我也有了娘家,有了婆家,但心里并没感觉到更加的安稳和平静,更多的是不...
    一瞬间的回转阅读 185评论 0 0