程式如何開始的
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)
)
複製程式碼
這樣每次傳送事件(點選按鈕之類的)我們都可以監聽到了。