iOS 常见文件及程序的启动原理

一、PCH 文件
PCH 是一个头文件,能被项目中的所有源文件共享和访问。

  1. PCH 文件的需求
    一个宏或者头文件等,很多文件都需要用到,怎么解决,搞个共用的头文件,同时导入这个头文件。
  2. 作用
    a. 存放一些共用的宏
    b. 存放一些共用的头文件
    c. 管理日志的输入,自定义LOG
  3. 为什么要管理日志输出
    因为日志输出非常耗性能,一般发布的时候不需要日志输出,只有调试的时候才需要。
  4. 注意
    在PCH 中写有关OC的方法,最好放在#ifdef OBJC中,xcode 在每个OC文件中都定义了这个宏,也就意味着只有OC文件才拥有这些宏,避免了项目文件中有C文件报错。

二、程序启动原理

  1. 程序启动过程
    a. 打开程序
    b. 执行main 函数
    c. 结束程序
  2. 执行Main 函数
    a. UIApplicationMian 函数原型:UIKIT_EXTERN int UIApplicationMain(int argc, char *argv[], NSString * __nullable principalClassName, NSString * __nullable delegateClassName);
    b. UIApplicationMian 的底层实现:
    (1). 根据principalClassName 提供的类名,创建一个UIApplication 对象。
    1. UIApplication 代表一个应用程序
    2. UIApplication 一般用来做一些应用级别的操作(app 的提醒框,联网状态,打电话,打开网页,控制状态)
      (2). 根据delegateClassName 提供的类名,创建一个UIApplication 对象。
    3. 程序加载完毕时调用:application:didFinishLaunchingWithOptions:
    4. 程序获取焦点时调用:applicationDidBecomeActive:
    5. 程序进入后台时调用:applicationDidEnterBackgroup:
    6. 程序失去焦点时调用:applicationWillResignActive:
    7. 程序从后台进入前台时调用:applicationWillEnterForegroup:
    8. 内存警告,可能要终止程序时调用:applicationDidReceviceMemoryWarning:
    9. 程序即将退出时调用:applicationWillTerminate:
      (3). 开启一个主运行循环,它是保存程序一直运行,并处理事件。
      (4). 加载info.plist 和启动图片,并且判断info.plist 有没有指定Main.storyboard,如果指定就去加载。
  3. application 隐藏状态栏
    (1). 设置Info.plist文件:添加健View controller-based status bar appearance,设置值为NO。
    (2). 创建application。
    (3). 调用隐藏状态栏的方法。
  4. 补充:反射机制
    反射机制的好处:如果类名用字符串表示,即使类名写错了,编辑器不会报错;通过反射机制类名写错了,编译器报错。
    NSString * class = NSStringFromClass([AppDelegate class]);
    appDelegate * strClass = NSClassFromString(@"AppDelegate");

三、加载Main.storyboard

  1. 加载Main.storyboard 步骤
    a. 创建窗口
    b. 加载Main.storyboard,并且加载Main.storyboard指定的控制器
    c. 把新的控制器作为窗口的根控制器,并让窗口显示出来
  2. 窗口Window
    a. UIWindow 是一个特殊的UIView, 在一个app 中一般都会有一个UIWindow ,但不仅只有一个,例如:键盘也是一个窗口
    b. app 程序启动完成后,创建的第一个视图控件就是UIWindow, 接着创建控制器的UIView,最后将控制器添加到Window上,于是控制器的view 就显示在屏幕上了。
    c. 一个app 之所以能显示在屏幕上,完全是因为有UIWindow。
    d. UIScreen :标识物理的屏幕,他连接着设备。
    e. UIWindow :用于提供绘制支持,提供了一些绘制方法。
    f. UIView :窗口上有很多view,是用于绘图操作的,把画好的view 添加到窗口上;屏幕上的东西都是绘制上去的,刷新一遍相当于重新绘制一遍。
    g. 只有加载Main.storyborad 的时候才创建窗口(加载:系统自动加载)
    h. 如果是自己用代码加载Main.storyborad 需要自己创建窗口代码。
  3. 补充
    a. 如果把新建的控制器的view用addSubview: 方法直接添加到窗口上,不会有旋转功能。
    b. 设置窗口的根视图控制器RootViewController,会自动把控制器的view添加到窗口。
    c. 查看主窗口:application.keyWindow
    d. 显示窗口:self.window.hidden = NO
    e. 查看程序的所有窗口:application.windows
  4. addSubView 和rootViewController 的区别
    a. 直接用addSubView,控制器会被释放,控制器就不能处理事件。
    b. 直接用addSubView,控制器的view不会旋转。
    c. 用rootViewController,控制器不会被释放,而且控制器的view会自动旋转。
    d. 旋转事件->UIApplication -> window -> rootViewController -> 旋转控制器view
  5. makeKeyAndVisible 方法底层做的事
    a. 把窗口设置成主窗口,如:application.keyWindow = self.window;
    b. 显示窗口,如:self.window.hidden = NO;
    c. 注意:虽然底层会做上面两步,但不一定是上面的代码。
  6. 窗口的层级
    a. windowLevel: UIWindowLevelNormal < UIWindowLevelStatusBar < UIWindowLevelAlert
    b. UIWindowLevelNormal :默认顶层层级
    c. UIWindowLevelStatusBar :状态栏、键盘
    d. UIWindowLevelAlert:UIAlertView 、UIActionSheet
    e. 把window 的层级设置成UIWindowLevelAlert ,就会显示在最前面了。
    f. 相同层级的窗口,想让其中一个显示,可以用那个窗口的层级加上一个数
  7. 代码模仿main.storyboard 加载
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIStoryboard * storyboard = [UIStoryboard storyboardWithName:@"main" bundle:nil];
    UIViewController * vc = [storyboard instantiateViewControllerWithIdentifier:@"B"]
    self.window.rootViewController = vc;

四、通过XIB 创建控制器的View

  1. 步骤
    a. 创建一个控制器类
    b. 创建一个xib,并指定所描述的控制器,一个xib 只能用来描述一个控制器,如果没有指定,就不能拖线指定控制器的view
    c. 拖线指定xib 中的哪个UIView 是控制器的view
  2. 只有控制器的init 的方法,底层才会调用initWithNibName:bundle:方法
  3. UIView 的创建
    a. 如果重写loadView ,就根据自定义view 去创建view
    b. 如果没有重写loadView,就去查看有没有storyboard,有storyboard,就根据storyboard 描述的view去创建
    c. 如果没有storyboard 就去看是否 有对于的XIB,有xib 就根据xib 的描述的view创建
    d. 如果没有xib, 即nibName == nil 时,就查有没有同名的xib,但是优先查看没有controller 的xib, 如果查不到与xib完全同名的xib,如:xib的拥有者是viewController ,xib 的文件名就是view,就优先查view.xib,根据它的描述的view创建;如果没有文件名的xib,就去查看名字为ViewController 的xib, 如果有就根据xib 里的描述的view 创建
  4. 控制器的loadView方法
    a. loadView的作用:自定义控制器view, 只要重写这个方法,说明要创建view,就不会自动创建view
    b. loadView 说明时候调用:第一次使用view的时候调用,调用这个方法创建控制器的view
    c. loadView 默认做法:如果storyboard 描述了控制器view,就去加载
    d. 注意:1.只要重写loadView方法,没有调用系统默认的做法,即不写[super loadView],就不会去加载storyboard或者xib来描述控制器的view 2.如果重写loadView方法,并且指定了nibName,loadView默认的做法会去加载xib的view 3. 只要重写loadView方法,没有指定nibName,就不会自动去加载和控制器同名的xib 4. 在重写loadView时,没有给self.view创建view,就使用self.view,会造成死循环 5. 如果是根控制器的view,自定义view的时候可以不设置尺寸,系统会自动设置;不是跟控制器就不行;可以用CGRctZeco表示,如:self.view = [[UIView alloc] initWithFrame: CGRctZeco]; 6. 重写loadView方法时,不要写[super loadView];,因为重写该方法的目的是自定义view,重写了还要去加载storyboard里的view,等于多此一举
  5. xib 和storyboard 的区别
    storyboard 已经指定了控制器view,不需要我们管,xib 需要我们手动管理。
  6. 如何快速生成一个xib 描述的控制器view
    1、定义新的控制器的时候,勾选xib,会自动搞一个xib描述控制器的view
    2、会自动生成一个和控制器同名的xib,并且里面设置好了

五、控制器view

  1. view的生命周期:只要是view开头的都是view的生命周期方法
    loadView:第一次使用view的时候调用
    viewDidLoad:控制器的view加载完成的时候调用
    viewWillAppear:控制器的view即将显示的时候调用
    viewDidAppear:控制器的view完全显示的时候调用
    viewWillDisappear:控制器的view即将消失的时候调用
    viewDidDisappear:控制器的view完全消失的时候调用
    viewWillLayoutSubviews:控制器的view即将布局的时候调用
    viewDidLayoutSubviews:控制器的view完全布局的时候调用
    viewWillUnload:控制器的view即将销毁
    viewDidUnload:控制器的view完全销毁
  2. 内存警告处理
    a、处理过程

有内存警告 -> 调用didReceiveMemoryWarning方法 -> 判断控制器的View存不
存在 ->
存在就判断能不能被释放(判断是不是正在显示在界面上) -> 能释放就调用ViewWillUnload ->
完全释放后就调用ViewDidUnload

b、注意

内存警告处理时,ViewWillUnload和ViewDidUnload不一定被调用,因为这是系统自动判断的

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

推荐阅读更多精彩内容