UIApplication简介

  1. UIApplication对象是应用程序的象征。
  2. 每一个应用程序都有自己的UIApplication对象,而且是单例。
  3. 一个iOS程序启动后创建的第一个对象就是UIApplication对象。
  4. 通过UIApplication *app = [UIApplication sharedApplication];可以获得这个单例对象。
  5. 利用UIApplication对象能进行一些应用级别的操作。

UIApplication单例实现原理

首先我们知道UIApplication对象是单例创建的,也就是说程序中UIApplication对象只创建一次,我们不能再新建UIApplicaiton对象。
那么当我们尝试新建一个UIApplicaiton对象时,
UIApplication *app = [[UIApplication alloc]init];
程序会报错,我们来看一下错误信息

'NSInternalInconsistencyException', reason: 'There can only be one UIApplication instance.'

这里我们发现系统的做法是抛出一个异常,告诉我们UIApplicaiton对象只能有一个。
这时我们基本可以理清,苹果内部如何实现UIApplication单例。

1.不能外界调用alloc,一调用就崩掉,抛出异常,(第一次调用alloc就不崩溃,其他都崩溃)
2.提供一个方法给外界获取单例(shareApplication)
3.程序启动的时候内部创建一次单例

下面我们来模仿一下系统单例的实现
创建Person类
Person.h

#import <Foundation/Foundation.h>

@interface Person : NSObject
//注:一般我们写单例的时候,也用shared开头,这是命名规范
+(instancetype)sharePerson; @end

Person.m

#import "Person.h"

@implementation Person
//静态变量
static Person *_person = nil;
//类加载:每次程序一启动就会把所有类加载进内存
+(void)load
{
_person = [[Person alloc]init];
} +(instancetype)sharePerson
{
return _person;
} +(instancetype)alloc
{
if (_person) {
// _person有值标示已经分配好了,就不允许外界在分配内存
// 抛异常,告诉外界不允许分配 // 创建异常类
// name:异常的名称
// reson:异常的原因
// userInfo:异常的信息
NSException *excp = [NSException exceptionWithName:@"NSInternalInconsistencyException" reason:@"There can only be one Person instance." userInfo:nil]; // 抛异常
[excp raise];
}
return [super alloc];
}
@end

此时单例Person类就实现了,当我们alloc Person实例化对象的时候就会抛出异常。

一个iOS程序启动后创建的第一个对象就是UIApplication对象

那么UIApplication对象是什么时候被创建的呢?这时我们找到程序的入口main.m

int main(int argc, char * argv[]) {
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

我们发现程序一开始返回了UIApplicationMain方法,并且还有4个参数
我们来看一下这些参数的介绍
argc

The count of arguments in argv; this usually is the corresponding parameter to main.

argv

A variable list of arguments; this usually is the corresponding parameter to main.

principalClassName

The name of the UIApplication class or subclass. If you specify nil, UIApplication is assumed.

delegateClassName

The name of the class from which the application delegate is instantiated. If principalClassName designates a subclass of UIApplication, you may designate the subclass as the delegate; the subclass instance receives the application-delegate messages. Specify nil if you load the delegate object from your application’s main nib file.

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

重点放在第三、四个参数

第三个参数 nil:代表UIApplication类名或者子类名称,nil 相当于 @"UIApplicaiton";
第四个参数 :代表UIApplicaiton的代理名称 NSStringFromClass([AppDelegate class] 相当于 @"AppDelegate";

此时我们可以根据UIApplicationMain函数了解程序启动的过程

  1. 根据传递的类名创建UIApplication对象,这是第一个对象
  2. 创建UIApplication代理对象,并给UIApplicaiton对象设置代理
  3. 开启主运行循环 main events loop处理事件,保持程序一直运行
  4. 加载info.plist,判断是否指定mian(xib 或者 storyboard)如果指定就去加载

利用UIApplication对象能进行一些应用级别的操作。

  • 设置应用程序图标右上角的红色提醒数字
    @property(nonatomic) NSInteger applicationIconBadgeNumber;
    代码实现和效果:

    UIApplication *app = [UIApplication sharedApplication];
    app.applicationIconBadgeNumber = 10;
    // 创建通知对象
    UIUserNotificationSettings *setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
    // 注册用户通知
    [app registerUserNotificationSettings:setting];

    注:苹果为了增强用户体验,在iOS8以后我们需要创建通知才能实现图标右上角提醒,iOS8之前直接设置applicationIconBadgeNumber的值即可。

提醒效果图
  • 设置联网指示器的可见性
    @property(nonatomic,getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
    代码实现和效果:

    app.networkActivityIndicatorVisible= YES;

    联网指示器显示效果图
  • 管理状态栏
    从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的设置,添加选中行,并设置为NO即可,这篇文章中有详细介绍iOS中用application 来管理电池栏状态

    Info.plist的设置

    代码:

    //通过sharedApplication获取该程序的UIApplication对象
    UIApplication *app=[UIApplication sharedApplication];
    //设置状态栏的样式
    //app.statusBarStyle=UIStatusBarStyleDefault;//默认(黑色)
    //设置为白色+动画效果
    [app setStatusBarStyle:UIStatusBarStyleLightContent animated:YES];
    //设置状态栏是否隐藏
    app.statusBarHidden=YES;
    //设置状态栏是否隐藏+动画效果
    [app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationFade];

    c.总结

    如果状态栏的样式只设置一次,那就用UIApplication来进行管理,并且UIApplication可以提供动画效果;
    如果状态栏是否隐藏,样式不一那就用每个控制器对自己的状态栏进行管理。

  • openURL:方法
    UIApplication有个功能十分强大的openURL:方法
    - (BOOL)openURL:(NSURL*)url;
    openURL:方法的部分功能有

    UIApplication *app = [UIApplicationsharedApplication];
    打电话 [app openURL:[NSURLURLWithString:@"tel://110"]];
    发短信 [app openURL:[NSURLURLWithString:@"sms://10086"]];
    发邮件 [app openURL:[NSURLURLWithString:@"mailto://xxcc@fox.com"]];
    打开一个网页资源 [app openURL:[NSURL URLWithString:@"http://www.baidu.com"]];
    打开其他app程序 openURL方法,可以打开其他APP。

    系统内部根据不同的头标示来做出不同的相应。

  • 判断程序运行状态

      //判断程序运行状态
    /*
    UIApplicationStateActive,
    UIApplicationStateInactive,
    UIApplicationStateBackground
    */
    UIApplication *app = [UIApplication sharedApplication];
    if(app.applicationState ==UIApplicationStateInactive){
    NSLog(@"程序在运行状态");
    }
  • 阻止屏幕变暗进入休眠状态
      //阻止屏幕变暗,慎重使用本功能,因为非常耗电。
    UIApplication *app = [UIApplication sharedApplication];
    app.idleTimerDisabled =YES;

UIApplication Delegate

当app收到干扰,例如程序运行中来电等,就会产生一些系统事件,这时UIApplicaiton会通知它的代理delegate对象,让delegate代理来处理这些系统事件。
delegate可以处理的时间包括

1.应用程序的生命周期事件(如程序启动和关闭)
2.系统事件(如来电)
3.内存警告(用处较多)

每当我们创建项目时,程序中的AppDelegate文件就是UIAppliacation的代理,我们可以发现它已经遵守了UIApplicationDelegate。

@interface AppDelegate : UIResponder <UIApplicationDelegate>
下面我们来看一下AppDelegate的方法

// AppDelegate:监听应用程序的生命周期
// 以下方法就是应用程序的生命周期方法 // 应用程序启动完成的时候就会调用AppDelegate的方法
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSLog(@"%s",__func__);
return YES;
}
// 当应用程序失去焦点的时候调用
- (void)applicationWillResignActive:(UIApplication *)application {
NSLog(@"%s",__func__);
}
// 当应用程序进入后台的时候调用
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSLog(@"%s",__func__);
// 保存一些信息
}
// 当应用程序进入前台的时候调用
- (void)applicationWillEnterForeground:(UIApplication *)application {
NSLog(@"%s",__func__);
}
// 当应用程序完全获取焦点的时候调用
// 只有当应用程序完全获取焦点的时候,才能够与用户交互
- (void)applicationDidBecomeActive:(UIApplication *)application {
NSLog(@"%s",__func__);
}
// 当应用程序关闭的时候
- (void)applicationWillTerminate:(UIApplication *)application { }
//收到内存警告时调用
-(void)applicationDidReceiveMemoryWarning:(UIApplication *)application{ }

作者:xx_cc
链接:http://www.jianshu.com/p/f0a2117406d8
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

iOS-UIApplication详解的更多相关文章

  1. 【转】iOS UIApplication详解

    1.状态栏UIStateBar的设置是在UIApplication里面设置的,它包含4中风格 2. - (void)beginIgnoringInteractionEvents; (void)endI ...

  2. 【转】IOS AutoLayout详解(三)用代码实现(附Demo下载)

    转载自:blog.csdn.net/hello_hwc IOS SDK详解 前言: 在开发的过程中,有时候创建View没办法通过Storyboard来进行,又需要AutoLayout,这时候用代码创建 ...

  3. IOS SDK详解

    来源:http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html?page=1#42803301 博客专栏>移动开发专栏>I ...

  4. iOS路由详解

    本文如题,路由详解,注定是一篇详细解释iOS路由原理及使用的文章,由于此时正在外地出差,无法详细一一写出,只能不定时的补充. 一.什么是iOS路由 路由一词来源于路由器,可以实现层级之间消息转发的功能 ...

  5. IOS 手势详解

    在IOS中手势可以让用户有很好的体验,因此我们有必要去了解一下手势. (在设置手势是有很多值得注意的地方) *是需要设置为Yes的点击无法响应* *要把手势添加到所需点击的View,否则无法响应* 手 ...

  6. IOS SizeClasses 详解

    SizeClasses 详解 iOS 8在应用界面的可视化设计上添加了一个新的特性-Size Classes.对于任何设备来说,界面的宽度和高度都只分为三种描述:紧凑,任意和宽松.这样开发者便可以无视 ...

  7. iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...

  8. iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...

  9. ios学习--详解IPhone动画效果类型及实现方法

    详解IPhone动画效果类型及实现方法是本文要介绍的内容,主要介绍了iphone中动画的实现方法,不多说,我们一起来看内容. 实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一 ...

  10. iOS之UIApplication详解

    UIApplication对象特点: 特点1: UIApplication对象是应用程序的象征,一个UIApplication对象就代表一个应用程序,而且是单例的.(用来封装整个应用程序的一个对象, ...

随机推荐

  1. Endnote导入共享数据

    Endnote导入共享数据 Endnote是我们经常使用的参考文献管理工具.但是,在云计算还不是很普及的今天,往往每台电脑上都有自己的endnote数据库.这样,换了电脑,要使用同样的参考文献数据时, ...

  2. meta标签的作用及整理

    [转载] meta的标签的使用是我在前端学习中曾经困惑过一段时间的问题.一方面不是很了解meta标签的用途,另一方面是对于meta标签里的属性和值不是懂,也不知道从哪里冒出来的,所以这篇文章专门整理下 ...

  3. 修改织梦data目录名

    1.修改include目录下的common.inc.php这个文件.打开文件,找到第24行: define('DEDEDATA', DEDEROOT.'/data'); 把data修改成为您要改的目录 ...

  4. 12) 十分钟学会android--APP通信传递消息之简单数据传输

    程序间可以互相通信是Android程序中最棒的功能之一.当一个功能已存在于其他app中,且并不是本程序的核心功能时,完全没有必要重新对其进行编写. 本章节会讲述一些通在不同程序之间通过使用Intent ...

  5. undefined reference to “boost” in Qt—Ubuntu

    一:使用PCL时遇到的问题 原因:缺少boost的lib包含: 在Pro文件里面添加: LIBS += -lboost_system .....................等库文件包含 二:编译B ...

  6. STL:使用string、vector、complex和limits

    (有少量修改!)使用到了STL的算法库: #include<algorithm> #include<vector> //属于STL库 模板库 写库的人为了和标准C和C++库区分 ...

  7. java必备技能

    Android应用程序开发是以Java语言为基础的,所以需要有扎实的Java基础知识.首先熟悉java基本语法,然后熟悉设计模式等. a) Java基础语法:看下面的<Java知识点列表> ...

  8. JeeSite 4.0 规划(二)

    ==== 点击放大查看 ==== ==== 点击放大查看 ====

  9. <转>统计源代码行数的一些实现方法

    这个问题的思考其实对于某一种语言而言,基本都能实现,只是简单和复杂而已.而此次我讨论就是只是在linux下面使用了shell和c对源代码进行行 数的讨论.本打算是实现一个python版本的,由于pyt ...

  10. apicloud开发方法。

    1.前端布局 window frame 子窗口 franmegroup  子窗口组. 一个页面比如有一个固定的顶部,然后中间区域是商品或者是什么内容,那么这个整体就是一个window,那么中间的就是i ...