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閱讀 228,606評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,582評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 176,540評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,028評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,801評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,223評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,294評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,442評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,976評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,800評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,996評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,543評論 5 360
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,233評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,926評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,702評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374

推薦閱讀更多精彩內容