Fork me on GitHub

9/24/2010

iPhone App 的基本流程

在開始寫 iPhone App 之前,對於 iPhone 程式整個的流程應該要有一個大致上的了解,不像之前在寫 C++ 程式一樣,iPhone 採用了 MVC, delegate 等等設計模式,那些新增專案自動產生出來的程式碼,似乎不是那麼容易讓人理解,於是我潛心鑽研了兩小時,在此記錄一下。



上面這張圖是擷取自 iOS Application Programming Guide,大概可以說明整個 App 是如何開始運作的。可以開一個 View-based Application 來對照看看上面這張圖是怎麼回事。

說到程式的進入點,第一個想到的就是 main function,當然 iPhone 程式也不例外,可以在 Group &Files 當中的 Other Sources 找到 main.m 這個檔案,當中定義了 main 函式如下:

int main(int argc, char *argv[]) {
   
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    int retVal = UIApplicationMain(argc, argv, nil, nil);
    [pool release];
    return retVal;
}


首先他建立了一個記憶體管理的 pool 這個先不用管他,重點是第二行 UIApplicationMain,是的,這個函式我將他理解成 UIApplication 的建立,也就是整個 iPhone App 開天闢地的天下第一 funciton。接著,由上方的流程圖可以看到,下一部就是連結 Application Delegate

但是,其實這個動作,當我們使用專案範本建立新專案的時候,Xcode 就幫我們做好了,假設你建立了一個名為 VB 的 View-based Application,那麼你可以看到兩個 delegate 檔案已經自動被建立好了 (VBAppDelegate.h 和 VBAppDelegate.m)。

打開 VBAppDelegate.h 來瞧瞧可以看到他的 interface 定義了兩個成員 (如下),一個是 UIWindow 另一個則是 VBViewController。可以看到 VBAppDelegate 其實是 conform 了 <UIApplicationDelegate> protocol,也就是說他是一個 custom object,請參照上圖,也就是說設計者可以新增一些任務在當中。

@interface VBAppDelegate : NSObject <UIApplicationDelegate> {
    UIWindow *window;
    VBViewController *viewController;
}


既然他叫做 AppDelegate,也就是說當 UIApplication 開始之後,會交代一些事情給 AppDelegate 去做,而 AppDelegate 所要做的最基本的事情就是建立一個 window 然後把一個空的 view 放進去 (就 View-based Application 而言)。

那麼,UIApplication 是怎麼告訴 UIApplication Delegate 要做事了呢,打開 Group & Files 當中 Resources 裡面的 MainWindow.xib 變可一窺究竟。.xib 稱之為 nib 檔,是用來描述 Application 的外表與其控制物件關係的檔案 (是以視覺化的方式呈現),總之,雙擊 MainWindow.xib 來瞧瞧,如下:



選取 File's Owner 可以看到,原來這個 nib 檔案的擁有者是 UIApplication,然後觀察他的連結部分,可以看到 UIApplication 有一個 Outlet 叫做 delegate,而且已經被 link 到 VBAppDelegate,是的,一切都是範本幫你建好好的,有了這個連結 UIApplication 就會在某個適當的時機將任務交派給 Application Delegate 去做。

接著看看 VBAppDelegate 做了哪些事,點選 VB App Delegate 看看他的連結狀況 (如下圖),可以看到它的兩個 Outlet 成員 viewController 和 window 都已經被範本幫你建立好的 View Controller 和 Window 元件給連上了。




稍微回顧整理一下,UIApplication 出現,然後叫 Application Delegate 做事,然後它建立了一個 window 和一個 view controller 並且把這個 view 丟到 window 當中,觀察 VBAppDelegate 的 application:didFinishLaunchingWithOptions: 函式可以得知!

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {   
   
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];

    return YES;
}


接著我們看看 View Controller 的連結狀況 (如下圖),咦,怎麼只有看到他被連結到 Application Delegate,它本身的 view Outlet 沒有被連結,空空如也呢?




Oh, 原來他是透過 NIB Name 將這個 View Controller 物件以另一個 nib 檔案來初始化,如下圖:




那麼,只要打開 VBViewController.xib 一切就水落石出啦,的確在這個 nib 檔案當中,View Controller 的成員 view (也是 outlet) 的確連結到一個空的 View 物件,真相大白!




以上大致就是透過專案範本所產生出來的現成程式碼所在做的事情,當然 App 在運行的途中可能會遭遇到許多的狀況,一個完整的運行流程在 這篇 文章中有詳細的圖解!引用該圖如下:





參考資料:Demystifying iPhone App Startup, Demystifying View Controllers and Views

......






No comments:

Post a Comment