swift 中的 @UIApplicationMain

程序如何開始的

C 系列語言中,程序的入口都是 main 函數,一個 Objective-C 的 iOS app 項目在新建時,Xcode 會給我們創建好一個 main.m 的文件。

#import <UIKit/UIKit.h>
#import "AppDelegate.h"

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

我們調用了 UIKit 的 UIApplicationMain 方法,這個方法根據第三個參數初始化一個 UIApplication 或者它的子類對象開始接收事件。當傳入 nil 時則使用默認的 UIApplication。最后一個參數指定了 AppDelegate 類作為應用的委托,用來接收與應用生命周期相關的委托方法。

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

- (void)applicationWillResignActive:(UIApplication *)application {
}

- (void)applicationDidEnterBackground:(UIApplication *)application {
}

- (void)applicationWillEnterForeground:(UIApplication *)application {
}

- (void)applicationDidBecomeActive:(UIApplication *)application {
}

- (void)applicationWillTerminate:(UIApplication *)application {
}

雖然這個方法標明要返回一個 int,但其實它并不會真正的返回,而是一直存在于內存中,直到用戶或者系統將應用強制終止。

swift 中的對應情況

創建一個 swift 的項目之后,我們發現所有的文件中并沒有一個類似于 Objective-C 中的 main.m 文件,也沒有 main 函數。唯一和 main 有關系的就是在 AppDelegate 中有一個 @UIApplicationMain 標簽。

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

}

這個標簽的作用就是將標注的類作為委托,創建一個 UIApplication 并啟動整個程序。一般情況我們不需要對這個標簽做任何修改,但如果我們想使用 UIApplication 的子類而不是它本身,我們就要自定義一個 main.swift 文件了(記得刪除 @UIApplicationMain 標簽)。這個文件我們不需要定義作用域,直接寫代碼就OK。

import UIKit

class MyApplication: UIApplication {
    override func sendEvent(_ event: UIEvent) {
        super.sendEvent(event)
        print("Event sent:\(event)")
    }
}

UIApplicationMain(
    CommandLine.argc,
    UnsafeMutableRawPointer(CommandLine.unsafeArgv)
        .bindMemory(
            to: UnsafeMutablePointer<Int8>.self,
            capacity: Int(CommandLine.argc)),
    NSStringFromClass(MyApplication.self),
    NSStringFromClass(AppDelegate.self)
)

這樣每次發送事件(點擊按鈕之類的)我們都可以監聽到了。

相關鏈接

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容