iOS 基礎01--專案檔案、applecation、啟動過程、VC生命週期

weixin_34107955發表於2018-09-18

iOS 基礎01--專案檔案、applecation、啟動過程、VC生命週期

1 專案中常見的檔案

  • 1 info.plist 檔案
    plist檔案是一個全域性配置檔案,系統預設就叫做info.plist,所以如果自己取名字千萬不可以取作info.plist;
    程式碼裡拿到info.plist裡的引數使用
[[NSBundle mainBundle]infoDictionary]; //這個字典拿到的就是info.plist裡的東西,比如獲取版本號
NSString * versionStr = [[[NSBundle mainBundle]infoDictionary] objectForKey:@"CFBundleShortVersionString"];

另一個需要注意的是info.plist裡的Bundle name就是我們手機桌面上顯示的app名字,系統預設的是取product name

  • 2 .pch 檔案
    這是一個全域性配置檔案,是需要自己手動建立的。在建立new file的最下面的other下有一個 pch file。生成完成之後,同樣需要自己配置一下。在build setting 裡搜 prefix header,把剛才自己新建的檔名的路徑拖進去。

  • 3 OC巨集
    這裡說的巨集就是大概要用在PCH檔案裡面的使用到,自己以前沒見過的:

#ifdef __OBJC__ //OC檔案中使用
 #ifdef DEBUG //在debug條件下執行
 #define FCFLog(...) NSLog(__VA_ARGS__) //自定義的列印函式
 #else
 #define FCFLog(...) //NSLog(__VA_ARGS__)
 #endif
#endif
  • 4 這裡順帶提一下蘋果沙盒檔案裡的檔案目錄

Documents、Library、tmp這三個資料夾。
1 Documents:蘋果建議將程式中瀏覽到的資料儲存到該目錄下,對使用者可見。這個目錄用於儲存使用者資料或其他應該定期備份的資訊
2 Library:這個資料夾下有兩個主要的子資料夾Caches和Preferences。Preferences檔案放的就是平時我們用NSUserDefaults存取的東西;Caches則主要存取我們自己下載的一些檔案資料。Library對使用者不可見。
3 tmp:是一個零時資料夾。儲存app啟動過程中產生的資訊。

Documents和Library資料夾在iCloud和iTunes備份的時候會被備份。tmp在iPhone重啟或app記憶體不夠的時候就會被清空。

2 UIApplication

UIApplication 是應用程式啟動之後建立的第一個物件,且是單例物件。
大部分應用級別的設定都可以使用UIApplication進行設定

  • 1 設定應用程式圖示上的未讀通知數
UIApplication * app = [UIApplication shareApplication];
UIUserNotificationSettings * setting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge categories:nil];
[app registerUserNotificationSettings:settings];
app.applicationIconBadgeNumber = 99;
  • 2 設定應用程式狀態列中正在請求網路的旋轉小標誌
UIApplication * app = [UIApplication shareApplication];
app.networkActivityIndicatorVIsible = YES;
  • 3 跳轉URL或app或打電話
//網址
UIApplication * app = [UIApplication shareApplication];
[app openURL:[NSURL URLWithString:@"https://www.baidu.com"] options:[[NSDictionary alloc] init] completionHandler:^(BOOL success) {
}]; 
//電話
[app openURL:[NSURL URLWithString:@"tel://10086"] options:[[NSDictionary alloc] init] completionHandler:^(BOOL success) {
}];
  • 4 AppDelegate 生命週期
1、didFinishLaunchingWithOptions      //app啟動完畢
2、applicationWillResignActive      //失去焦點:失去和使用者的互動能力
3、applicationDidEnterBackground      //app已經進入後臺——一般用來儲存資料
4、applicationWillEnterForeground     //進入前臺
5、applicationDidBecomeActive     //擁有焦點,恢復互動能力
6、applicationWillTerminate          //app銷燬的時候呼叫
     app啟動會呼叫: 1——5
     app進入後臺依次呼叫: 2——3
     app進入前臺依次呼叫: 4——5
     app殺死依次呼叫: 2——3——6

3 App啟動過程和原理

main函式之前:
作業系統iOS一開機就開始啟動一個系統的Runloop函式,以每秒60次的幀率不斷監聽這手機介面的使用者互動事件。一旦觸控就會觸發一個觸控事件,然後將事件放入事件佇列,緊接著就會通過埠找到對應的app,然後呼叫app的main函式——也就是OC檔案中的main.m檔案中的main函式

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

main函式裡呼叫了UIApplicationMain函式。UIApplicationMain的第三個引數要麼是UIApplication,要麼是UIApplication的子類,第四個引數則是確定UIApplication的代理是誰。

UIApplicationMain
     UIApplicationMain函式則建立UIApplication物件,設定UIApplicationMainDelegate代理
     接著,開啟事件迴圈(訊息迴圈) 開啟Runloop --> 載入info.plist -->如果設定了MainInterface,就載入對應的storyboard(建立window 建立初始化控制器)

4 Window

程式啟動過後建立的第一個檢視控制元件就是UIWindow,預設就是全屏的;
如果沒有在info.plist裡設定mian interface,那麼就得我們自己在app啟動之後(didFinishLaunchingWithOptions中)自己去建立一個window;
如果要讓window顯示則必須滿足兩個條件:

  • 1、給window設定rootViewcontroller;
  • 2、呼叫makekeyandvisible讓其可見:
_window = [[UIWindow alloc] init]; //預設的
_window.backgroundColor = [UIColorredColor];
_window.rootViewController = [[UIViewControlleralloc] init];
[_window makeKeyAndVisible];

程式會有多個window,但是隻有一個keywindow。而且是最後執行makeKeyAndVisible的window才是主視窗,注意這個和window的frame是沒有關係的:
建立第一個window

_window = [[UIWindow alloc] init]; //預設的
    _window.backgroundColor = [UIColor redColor];
    _window.rootViewController = [[UIViewController alloc] init];
    [_window makeKeyAndVisible];

建立第二個window

_window1 = [[UIWindow alloc] init]; //預設的
    _window1.backgroundColor = [UIColor blueColor];
    _window1.frame = CGRectMake(20, 20, 100, 200);
    _window1.rootViewController = [[UIViewController alloc] init];
    [_window1 makeKeyAndVisible];

在keywindow上加一個view

UIView * test = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    test.backgroundColor = [UIColor yellowColor];
    [[UIApplication sharedApplication].keyWindow addSubview:test];

說明keywindow是window1

window有三個層級:UIWindowLevelNormal、UIWindowLevelAlert、UIWindowLevelStatusBar

如果沒有設定level,則window就是按照makeKeyAndVisible的呼叫順序依次新增進去的。如果設定了層級,則層級從最底層到最上層依次是UIWindowLevelNormal——UIWindowLevelStatusBar——UIWindowLevelAlert

5 ViewController

UIViewController的各種建立方式

  • 1、[alloc init]純程式碼建立控制器,預設的frame就是全屏的,而且是透明色
FCFViewController * FCFVC = [[FCFViewController alloc]init];
  • 2、第二種方法,通過storyboard載入
UIStoryboard * sb = [UIStoryboard storyboardWithName:@"Test" bundle:nil];
01
 FCFViewController * FCFVC = [sb instantiateInitialViewController]; //這個函式返回storyboard中initial(也就是箭頭所指的view controller,這裡需要自己去storyboad中把那個Is Initial View Controller勾上)的view controller
02
 FCFViewController * FCFVC = [sb instantiateViewControllerWithIdentifier:@"switch"]; 
//這個函式就是根據storyboard裡view controller的對應的Storyboard id識別符號拿到的view controller
  • 3、第三種方式,通過xib載入,這裡是建立View Controller不勾選建立xib,單獨建立一個xib
/* 建立一個xib,不要修改xib裡的任何東西
  *File's Owner :所有者,改成view controller的類名
  * 連線view :將xib的view作為所有者VC的view
  */
 FCFViewController * FCFVC = [[FCFViewController alloc] initWithNibName:@"Text" bundle:nil]; //這裡返回的是控制器vc

6 View

  • 1、 純程式碼 ,建立一個透明色,且frame和螢幕一樣大的view
TestViewController * vc = [[TestViewController alloc]init];
  • 2、sb建立,就是storyboard裡面的view
TestViewController * vc = [[UIStoryboard storyboardWithName:@"Test" bundle:nil] instantiateInitialViewController];
  • 3、xib 指定xib,view就是xib裡描述的一樣
TestViewController * vc = [[TestViewController alloc] initWithNibName:@"View" bundle:nil];
  • 4、xib 建立同名xib,就是在單獨建立xib的時候把xib的名稱寫成VC的名稱,同樣正常配置File's owner 和 連線view, alloc init就可以了,系統會找同名的xib-"TestViewController",如果沒有就載入同名的不帶Controller的xib-"TestView".
TestViewController * vc = [[TestViewController alloc]init]; //先找TestViewController,再找TestView

7、ViewController生命週期

  • 1、這裡最關鍵的兩點就是loadView的執行時機和viewDidLoad的執行時機。
    loadView是懶載入,如果我們沒有在init方法是使用self.view,正常的載入順序就是init執行完之後——>執行loadview——>執行viewDidLoad。但是因為loadView是懶載入,所以在init方法裡面呼叫了self.view,那麼在用到self.view的時候就會馬上執行loadView,執行完loadView馬上會執行viewDidLoad,然後才返回init方法裡執行self.view之後的程式碼,例項:
@interface TestController ()
@property (nonatomic, assign)BOOL boolvalue;
@end

@implementation TestController

- (instancetype)init
{
  self = [super init];
  if (self) {
  NSLog(@"1");
  self.view.backgroundColor = [UIColor redColor];
  self.boolvalue = YES;
  NSLog(@"2");
  }
  return self;
}

- (void)loadView{
  NSLog(@"3");
  self.view = [UIView new];
  NSLog(@"4");
}

- (void)viewDidLoad {
  [super viewDidLoad];
  NSLog(@"5");
  if (self.boolvalue) {
  NSLog(@"6");
  }
  NSLog(@"7");
}

這裡執行的結果是:1、3、4、5、7、2。注意這裡不會執行6,因為那時還沒執行self.boolvalue=YES,而BOOL的預設值是false。

如果這裡把self.view.backgroundColor = [UIColor redColor];註釋掉,則執行的結果就是:1、2、3、4、5、6、7

可以去github上檢視Demo,喜歡的話star一下哦
github
CSDN

相關文章