国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - IOS - 詳解iOS應用程序的啟動過程

詳解iOS應用程序的啟動過程

2021-01-11 16:45ForeverYoung21 IOS

這篇文章主要介紹了iOS應用程序的啟動過程,講述了從其執行main函數開始到展示UIWindow的流程中的一些關鍵點,需要的朋友可以參考下

關鍵步驟
一個程序從main函數開始啟動。

復制代碼 代碼如下:

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


可以看到main函數會調用UIApplicationMain函數,它的四個參數的意思是:

 

  • argc: 代表程序在進入main函數時的參數的個數。默認為1。
  • argv: 代表包含的各個參數。默認為程序的名字。
  • principalClassName: UIApplication或者它的子類的名字, 如果傳入的是nil, 則表示UIApplication的名字, 即@"UIApplication"。
  • delegateClassName: UIApplication的代理的名字。

在UIApplicationMain函數中,根據傳入的UIApplication名稱和它的代理的名稱,會主要做下面的事情:

  • 根據傳入的名稱創建UIApplication對象。
  • 根據傳入的代理名稱創建UIApplication代理對象。
  • 開啟事件循環(如果不進行循環,那么在main函數結束后程序就結束了。要保證程序創建后可以一直存在)。
  • 解析Info.plist文件:

會在Info.plist文件里查找Main storyboard file base name這個Key對應的Value是否有值。如果有值,則表示之后會通過Storyboard加載控制器,AppDelegate會接收到didFinishLaunchingWithOptions消息(程序啟動完成的時候),此時Storyboard會進行一系列的加載操作(后面會具體說);如果沒有值,則不會通過Storyboard加載控制器,接著AppDelegate會接收到didFinishLaunchingWithOptions消息(程序啟動完成的時候),在這個時候需要我們通過代碼的方式加載控制器。

注意Info.plist中Main storyboard file base name這個Key并不是真正的Key,而是蘋果為了增強可讀性才這樣寫的,真正的Key為UIMainStoryboardFile(可以通過Info.plist文件的源代碼查看)。
這就是在想要用代碼方式創建控制器而不是Storyboard創建控制器的時候為什么先要將Main Interface設置為空白,這樣在解析Info.plist文件的時候才會知道不通過Storyboard創建控制器。
由此可以知道,解析Info.plist文件這一操作主要是看我們用的是Storyboard方式加載還是代碼的方式加載。默認Main storyboard file base name為Main,也就是通過Storyboard方式加載控制器。
現在具體分析一下,通過Storyboard方式加載控制器和代碼方式加載控制器。

通過Storyboard
通過Storyboard,主要做了下面的事情(這些事情不需要我們做,是系統自動完成的,在程序啟動完成的時候):

創建窗口。

創建一個UIWindow的實例用來顯示界面。

設置窗口的根控制器。

根據Storyboard的設置,創建一個控制器。
并且設置這個控制器為之前創建的window的根控制器。
顯示窗口。(相當于后面提到的makeKeyAndVisible)

設置self.window可見并且設置UIApplication的keyWindow。

在這一步中將根控制器的view添加到window上。

通過代碼方式
通過代碼的方式,需要我們在didFinishLaunchingWithOptions方法中進行加載控制器的相關操作。

復制代碼 代碼如下:


- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

 

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    UIViewController *viewController = [[UIViewController alloc] init];
    self.window.rootViewController = viewController;
    // 此時根控制器的view還沒有加到self.window上
    [self.window makeKeyAndVisible];
    // 此時根控制器的view加到self.window上
    return YES;
}


其實這里所做和系統所做是一樣的。(相當于系統的做法)

 

首先創建窗口,得到一個正確的UIWindow實例對象用來顯示界面。(self.window是系統自帶的屬性)

接著設置窗口的根控制器。

不再根據Storyboard中的設置加載,此時需要我們自己創建控制器。
設置這個控制器為self.window的根控制器。
注意這個時候根控制器的view還沒有加到self.window上,當窗口要顯示的時候,才會把窗口的根控制器的view添加到窗口。(可以輸出self.window.subViews來驗證)
顯示窗口。

復制代碼 代碼如下:

[self.window makeKeyAndVisible]實際上做了下面的事:


首先,將self.window設置為UIApplication的keyWindow,這么做是方便我們以后查看UIApplication的主窗口是哪一個。

 

接著,讓self.window可見,相當于執行的代碼是:

復制代碼 代碼如下:

self.window.hidden = NO;


這么做的原因是self.window默認hidden = YES,所以需要讓其顯示出來。

 

那么既然makeKeyAndVisible執行的是以上的操作,實際上將[self.window makeKeyAndVisible]替換為self.window.hidden = NO,那么界面也會正常顯示出來,因為makeKeyAndVisible內部就是這么做的。但是此時并沒有設置UIApplication的keyWindow,為了以后方便訪問,還是用makeKeyAndVisible更好一點。

經過這一步,界面將要顯示,此時根控制器的view會加到self.window上以正常顯示。

這里有一點要注意:

系統創建的AppDelegate自帶一個屬性位于.h文件中:

復制代碼 代碼如下:

@property (strong, nonatomic) UIWindow *window;


當用Storyboard的方式加載控制器,在應用啟動完成的時候(didFinishLaunchingWithOptions)需要一個UIWindow的實例來顯示界面,所以Apple提供了這個window屬性。系統根據storyboard自動創建一個window,然后將window賦值給這個window屬性,以保證完成之后的工作。

 

當用代碼的方式加載控制器,同樣的,首先也需要一個UIWindow的實例來顯示界面,因為不使用Storyboard所以這次要我們自己創建window。此時有兩種做法,第一種是在didFinishLaunchingWithOptions方法中創建一個UIWindow對象:

復制代碼 代碼如下:

UIWindow *myWindow = [[UIWindow alloc] initWithFrame:...];


但是如果用這種方法運行程序會發現界面依然無法顯示出來,因為此時myWindow是一個局部變量,當didFinishLaunchingWithOptions方法執行完畢這個變量就會銷毀。所以更好的辦法是直接使用系統提供的window屬性:

復制代碼 代碼如下:

self.window = [[UIWindow alloc] initWithFrame:...];


之前的例子也是這么做的。

 

另外,仔細觀察會發現這個window屬性的修飾符是strong,而不是weak。想想之前使用weak來修飾一個控件是因為這個控件會被加到一個view中,這個view的subViews數組會有強引用指向控件,所以用weak是沒有問題的。現在這種情況,因為window控件不會被加到其他view中,即沒有其他的強指針指向這個對象,所以在創建的時候需要將修飾符設置成strong以保證創建出的window不會被銷毀。(Apple創建的window屬性的修飾符是strong)

UIWindow的補充
window是有層級的,并且可以有多個window同時存在。比如:狀態欄就是一個window,鍵盤也是一個window。

可以通過設置UIWindow的對象的windowLevel屬性來調整層級。

self.window.windowLevel = UIWindowLevelStatusBar;
window共有三種等級:UIWindowLevelNormal,UIWindowLevelStatusBar UIWindowLevelAlert。如果三種等級同時出現在屏幕上,那么alert在最上面,statusBar在中間,normal則在最下面。

注意:如果一個程序中有多個window,控制器默認會把狀態欄隱藏。

解決辦法:關閉控制器對狀態欄的控制,(為Info.plist增加View controller-based status bar appearance這個key并設置為NO)這樣這些window以及狀態欄就可以按層級關系正常顯示。

概覽
這里PY為前綴名:

1.先執行main函數,main內部會調用UIApplicationMain函數

2.UIApplicationMain函數里面做了什么事情:

(1)創建UIApplication對象

(2)創建UIApplication的delegate對象—–PYAppDelegate

(3)開啟一個消息循環:每監聽到對應的系統事件時,就會通知MJAppDelegate

(4)為應用程序創建一個UIWindow對象(繼承自UIView),設置為PYAppDelegate的window屬性

(5)加載Info.plist文件,讀取最主要storyboard文件的名稱

(6)加載最主要的storyboard文件,創建白色箭頭所指的控制器對象

(7)并且設置第6步創建的控制器為UIWindow的rootViewController屬性(根控制器)

(8)展示UIWindow,展示之前會將添加rootViewController的view到UIWindow上面(在這一步才會創建控制器的view)

復制代碼 代碼如下:

[window addSubview: window.rootViewControler.view];


進入main函數,在main.m的main函數中執行了UIApplicationMain這個方法,這是ios程序的入口點!

復制代碼 代碼如下:

int UIApplicationMain(int argc, char argv[], NSString principalClassName, NSString *delegateClassName)


argc、argv:ISO C標準main函數的參數,直接傳遞給UIApplicationMain進行相關處理即可

 

principalClassName:指定應用程序類,該類必須是UIApplication(或子類)。如果為nil,則用UIApplication類作為默認值

delegateClassName:指定應用程序類的代理類,該類必須遵守UIApplicationDelegate協議

此函數會根據principalClassName創建UIApplication對象,根據delegateClassName創建一個delegate對象,并將該delegate對象賦值給UIApplication對象中的delegate屬性

lUIApplication對象會依次給delegate對象發送不同的消息,接著會建立應用程序的main runloop(事件循環),進行事件的處理(首先會調用delegate對象的 application:didFinishLaunchingWithOptions:)

程序正常退出時這個函數才返回。如果進程要被系統強制殺死,一般這個函數還沒來得及返回進程就終止了

下面我們有圖有真相吧!!!

延伸 · 閱讀

精彩推薦
  • IOS詳解iOS中多個網絡請求的同步問題總結

    詳解iOS中多個網絡請求的同步問題總結

    這篇文章主要介紹了詳解iOS中多個網絡請求的同步問題總結,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧...

    liang199111302021-03-15
  • IOSiOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果

    這篇文章主要介紹了iOS自定義UICollectionViewFlowLayout實現圖片瀏覽效果的相關資料,需要的朋友可以參考下...

    jiangamh8882021-01-11
  • IOSiOS中MD5加密算法的介紹和使用

    iOS中MD5加密算法的介紹和使用

    MD5加密是最常用的加密方法之一,是從一段字符串中通過相應特征生成一段32位的數字字母混合碼。對輸入信息生成唯一的128位散列值(32個字符)。這篇文...

    LYSNote5432021-02-04
  • IOSiOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)

    iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和

    這篇文章主要介紹了iOS中滑動控制屏幕亮度和系統音量(附加AVAudioPlayer基本用法和Masonry簡單使用)的相關資料,需要的朋友可以參考下...

    CodingFire13652021-02-26
  • IOSiOS開發之視圖切換

    iOS開發之視圖切換

    在iOS開發中視圖的切換是很頻繁的,獨立的視圖應用在實際開發過程中并不常見,除非你的應用足夠簡單。在iOS開發中常用的視圖切換有三種,今天我們將...

    執著丶執念5272021-01-16
  • IOSiOS開發技巧之狀態欄字體顏色的設置方法

    iOS開發技巧之狀態欄字體顏色的設置方法

    有時候我們需要根據不同的背景修改狀態欄字體的顏色,下面這篇文章主要給大家介紹了關于iOS開發技巧之狀態欄字體顏色的設置方法,文中通過示例代碼...

    夢想家-mxj8922021-05-10
  • IOSiOS實現控制屏幕常亮不變暗的方法示例

    iOS實現控制屏幕常亮不變暗的方法示例

    最近在工作中遇到了要將iOS屏幕保持常亮的需求,所以下面這篇文章主要給大家介紹了關于利用iOS如何實現控制屏幕常亮不變暗的方法,文中給出了詳細的...

    隨風13332021-04-02
  • IOSiOS中UILabel實現長按復制功能實例代碼

    iOS中UILabel實現長按復制功能實例代碼

    在iOS開發過程中,有時候會用到UILabel展示的內容,那么就設計到點擊UILabel復制它上面展示的內容的功能,也就是Label長按復制功能,下面這篇文章主要給大...

    devilx12792021-04-02
主站蜘蛛池模板: 日韩av在线电影 | 羞羞的视频在线免费观看 | 久久久免费精品视频 | 久久久久久亚洲av毛片大全 | 日本三级中文在线电影 | 色婷婷精品国产一区二区三区 | 亚洲情av | 国产精品久久久久久久久久免费动 | 自拍偷拍精品 | 在线免费观看a视频 | 青青操av在线| 免费看国产黄色 | 免费的av| 国产成人三区 | 羞羞影院| 欧美精品免费在线 | 日韩中文视频 | 欧美大片免费高清观看 | 99re| 中文字幕高清在线播放 | 亚洲精品欧美 | 伊人久色| 北条麻妃99精品青青久久 | 国产精品视频入口 | 亚洲在线看 | 日韩高清在线一区 | 久热久爱 | 高清一区二区三区 | 久久免费视频9 | 成人精品一区二区三区中文字幕 | 国产午夜在线 | 国产日韩一区二区 | 国产精品一区二区在线观看 | 国产高清视频一区 | 亚洲欧美日韩国产 | 日韩视频在线一区二区 | 精品国产91乱码一区二区三区 | av网站在线看 | 成人自拍视频 | 国产精品九九九 | 久久久999国产 |