No1 程序启动原理

一 Xcode5和Xcode6区别

  • Xcode5

    • Frameworks文件夹:存放iOS中常见的框架
    • pch文件
  • Xcode6

    • 没有Frameworks,会自动导入常见的框架
    • 没有pch
    • LaunchScreen.xib: 设置项目启动的界面

二 info.plist文件

  • 建立一个工程后,会在Supporting files文件夹下看到一个“工程名-Info.plist”的文件,该文件对工程做一些运行期的配置,非常重要,不能删除
    No1 程序启动原理_第1张图片

  • 1>Bundle name : app名称,项目通常使用英文,app名称显示中文

  • 2>Bundle identifier : app标识符 上传AppStore和推送

  • 3>Bundle versions string, short app版本号

  • 案例需求:获取当前app的版本号

 // 1.加载info.plist,解析出来字典
   // 获取资源文件的全路径
   NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Info.plist" ofType:nil];
   // File:文件的全路径
   NSDictionary *infoDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
  // 2.从字典读取数据
  NSString *curVersion = infoDict[@"CFBundleShortVersionString"];

    NSLog(@"%@",curVersion);
  • 简写代码
  NSDictionary *infoDict = [NSBundle mainBundle].infoDictionary;

  NSString *curVersion = infoDict[@"CFBundleShortVersionString"];

  NSLog(@"%@",curVersion);

三 pch文件

  • pch作用:

    • 1.存放一些公用的宏
    • 2.存放一些公用的头文件
    • 3.自定义Log
 // ...表示宏里面的可变参数
 // __VA_ARGS__表示函数里面的可变参数

 #ifdef DEBUG // 表示当前调试阶段

#define XMGLog(...) NSLog(__VA_ARGS__)

#else // 发布阶段

#define XMGLog(...)

#endif

pch原理:就是把pch文件中的所有内容拷贝到所有文件的头部

注意点:
pch文件一定要注意做些判断,判断下当前是否是OC文件,如果是就 导入OC的代码
所有的OC文件都会定义__OBJC__这个宏,苹果定义

四 UIApplication

  • UIApplication对象是应用程序的象征

    • 每一个应用都有自己的UIApplication对象,而且是单例的
    • 通过[UIApplication sharedApplication]可以获得这个单例对象
    • 一个iOS程序启动后创建的第一个对象就是UIApplication对象
    • 利用UIApplication对象,能进行一些应用级别的操作

      • 设置应用程序图标右上角的红色提醒数字 applicationIconBadgeNumber
      • 联网指示器的可见性networkActivityIndicatorVisible
      • 设置状态栏

        系统提供了2种管理状态栏的方式
        1>通过UIViewController管理(每一个UIViewController都可以拥有自己不同的状态栏)
        // 状态栏的样式 - (UIStatusBarStyle)preferredStatusBarStyle; 
        // 状态栏的可见性 - (BOOL)prefersStatusBarHidden; 
        
        2>通过UIApplication管理(一个应用程序的状态栏都由它统一管理)
        
      • 利用UIApplication来管理状态栏,首先得修改Info.plist的设置
        这里写图片描述

      • 打开资源,电话,网页,发短信

// UIApplication有个功能十分强大的openURL:方法 - (BOOL)openURL:(NSURL*)url;
// 打电话
UIApplication *app = [UIApplication sharedApplication];
[app openURL:[NSURL URLWithString:@"tel://10086"]];

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

// 发邮件
[app openURL:[NSURL URLWithString:@"mailto://[email protected]"]];

// 打开一个网页资源
[app openURL:[NSURL URLWithString:@"http://ios.itcast.cn"]];
  • 代码案例
 // 获取应用程序的象征
   UIApplication *app = [UIApplication sharedApplication];

    // 应用程序图片的提醒数字
    app.applicationIconBadgeNumber = 100;

    // 创建通知对象
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];

    // 注册用户通知
    [app registerUserNotificationSettings:settings];
    // 联网状态
    app.networkActivityIndicatorVisible = YES;

   // app.statusBarHidden = YES; 没有修改Info.plist的话没效果
  • 在iOS7之后,状态栏默认交给控制器处理
    • 控制器决定状态
- (BOOL)prefersStatusBarHidden
{
    return YES;
}
- (IBAction)btnClick:(id)sender {
    // 获取应用程序的象征
    UIApplication *app =  [UIApplication sharedApplication];
    // 隐藏状态栏
// [app setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];
   // 协议头:用来判断使用什么软件打开
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];

    [app openURL:url];
}

四 UIApplication代理

  • 在app受到干扰时,会产生一些系统事件,这时UIApplication会通知它的delegate对象,让delegate代理来处理这些系统事件

  • delegate可处理的事件包括:

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

No1 程序启动原理_第2张图片

  • iOS程序的启动过程

No1 程序启动原理_第3张图片

  • main -> UIApplicationMain, UIApplicationMain底层做事情

    • 1.创建UIApplication对象
    • 2.创建UIApplication的代理对象,而且给UIApplication对象代理属性赋值
    • 3.开启主运行循环,作用接收事件,让程序一直运行
    • 4.加载info.plist,判断下有木有指定main.storyboard,如果指定就会去加载
  • UIApplicationMain

    • main函数中执行了一个UIApplicationMain这个函数
   int UIApplicationMain(int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName);

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

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

    delegateClassName:指定应用程序的代理类,该类必须遵守UIApplicationDelegate协议
  int main(int argc, char * argv[]) {
    @autoreleasepool {
       // 注释代码是等价的
       // return UIApplicationMain(argc, argv, nil, @"XXAppDelegate");
       // return UIApplicationMain(argc, argv, @"UIApplication", @"XXAppDelegate");
        return UIApplicationMain(argc, argv, NSStringFromClass([UIApplication class]), NSStringFromClass([XXAppDelegate class]));
    }
 }

五 UIWindow

  • UIWindow是一种特殊的UIView,通常在一个app中至少会有一个UIWindow

  • iOS程序启动完毕后,创建的第一个视图控件就是UIWindow,接着创建控制器的view,最后将控制器的view添加到UIWindow上,于是控制器的view就显示在屏幕上了

  • 一个iOS程序之所以能显示到屏幕上,完全是因为它有UIWindow,也就说,没有UIWindow,就看不见任何UI界面
// 在加载info.plist文件之后,程序启动才完成
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 窗口显示的注意点:
    // 1.一定要强引用
    // 2.控件要想显示出来,必须要有尺寸

    // 1.创建窗口
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];

    // 设置窗口的颜色
    self.window.backgroundColor = [UIColor purpleColor];

    // 2.创建根控制器,在设置窗口的根控制器
    UIViewController *vc = [[UIViewController alloc] init];
    [vc.view addSubview:[UIButton buttonWithType:UIButtonTypeContactAdd]];

    // 设置窗口的根控制器,底层会自动把根控制器的view添加到窗口上,并且让控制器的view有旋转功能
    self.window.rootViewController = vc;
// [self.window addSubview:vc.view]; 不支持view旋转

    // 3.显示窗口
    // makeKeyAndVisible:让窗口成为应用程序的主窗口,并且显示窗口
    [self.window makeKeyAndVisible];

    return YES;
}
  • 弹出键盘
// 注意点:如果一个键盘想要弹出来,必须把textField添加到一个控件上.
   UITextField *textF = [[UITextField alloc] init];
   [textF becomeFirstResponder];
   [self.window addSubview:textF];
  • 窗口层级关系
    • 窗口的层级的级别 UIWindowLevelAlert > UIWindowLevelStatusBar > UIWindowLevelNormal
    • 设置窗口的层级,层级谁大就显示在最外面

No1 程序启动原理_第4张图片

  • 程序启动完整过程:
    • 1.main函数
    • 2.UIApplicationMain
      • 创建UIApplication对象
      • 创建UIApplication的delegate对象
    • 3.delegate对象开始处理(监听)系统事件(没有storyboard)
      • 程序启动完毕的时候,就会调用代理的application:didFinishLaunchingWithOptions:方法
      • 在application:didFinishLaunchingWithOptions:中创建UIWindow
      • 创建和设置UIWindow的rootViewController
      • 显示窗口
    • 4.根据Info.plist获得主要storyboard的文件名,加载最主要的storyboard(有storyboard)
      • 创建UIWindow
      • 创建和设置UIWindow的rootViewController
      • 显示窗口

你可能感兴趣的:(ios,程序启动,UIWindow)