App 启动流程
问题
从点击 App 图标到首屏展示,经历了哪些流程?
答案
完整启动流程
pre-main 阶段
- dyld:加载可执行文件和动态库
- Rebase/Bind:修正指针地址
- ObjC Runtime:注册类、Category、Protocol
- +load 方法:所有类的 +load 按顺序执行
- C++ 静态构造函数
post-main 阶段
// UIKit 生命周期
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// 1. 初始化核心 SDK
// 2. 配置第三方库
// 3. 创建根视图控制器
return true
}
}
// SwiftUI 生命周期
@main
struct MyApp: App {
init() {
// 初始化
}
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
SceneDelegate(iOS 13+)
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else { return }
window = UIWindow(windowScene: windowScene)
window?.rootViewController = MainTabBarController()
window?.makeKeyAndVisible()
}
}
常见面试问题
Q1: AppDelegate 和 SceneDelegate 的关系?
答案:iOS 13 引入多窗口支持,将 UI 相关职责从 AppDelegate 移到 SceneDelegate。AppDelegate 负责进程级事件(启动、推送 Token),SceneDelegate 负责 UI 级事件(前后台切换、窗口创建)。iPad 可以有多个 Scene 实例。
Q2: @main 宏做了什么?
答案:@main 替代了 main.swift,自动生成 main() 函数调用 UIApplicationMain() 或 SwiftUI 的入口。