iOS应用(App)生命周期、视图控制器(UIViewController)生命周期和视图(UIView)生命周期

清晰的理解它们能帮你更好地管理应用状态和资源。

一、iOS 应用(App)生命周期

应用生命周期描述了 App 从启动到终止的整个过程,由UIApplicationDelegate(应用代理)来管理。

核心阶段与代理方法(按执行顺序)

swift 复制代码
import UIKit

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    // 1. App启动完成(最核心的入口)
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        print("应用启动完成 - didFinishLaunchingWithOptions")

        // 通常在这里初始化根视图控制器、配置全局设置等

        return true

    }


    // 2. App即将进入前台(还未激活,可做界面刷新)
    func applicationWillEnterForeground(_ application: UIApplication) {
    
        print("即将进入前台 - applicationWillEnterForeground")

    }


    // 3. App已进入前台并激活(用户可交互)
    func applicationDidBecomeActive(_ application: UIApplication) {

        print("已激活 - applicationDidBecomeActive")

        // 恢复定时器、重新开始播放音频、刷新数据等

    }

    // 4. App即将进入后台(用户按Home键/切换App)
    func applicationWillResignActive(_ application: UIApplication) {

        print("即将失活 - applicationWillResignActive")

        // 暂停定时器、保存临时数据、暂停音频播放等

    }


    // 5. App已进入后台
    func applicationDidEnterBackground(_ application: UIApplication) {

        print("已进入后台 - applicationDidEnterBackground")

        // 持久化数据、释放不必要的资源(有大约5秒时间,耗时操作需申请后台任务)

    }

    // 6. App即将终止(仅在后台时可能触发,如系统回收内存)
    func applicationWillTerminate(_ application: UIApplication) {

        print("即将终止 - applicationWillTerminate")

        // 最终的资源清理、数据保存

    }

}

关键说明

  • 启动流程 :用户点击 App 图标 → 系统加载可执行文件 → 调用didFinishLaunchingWithOptions → 显示界面 → 进入活跃状态。
  • 后台与前台切换 :活跃 → 失活(WillResignActive)→ 后台(DidEnterBackground)→ 前台(WillEnterForeground)→ 活跃(DidBecomeActive)。
  • 终止 :后台状态下系统回收内存,触发applicationWillTerminate(若 App 在前台,直接终止,不触发此方法)。

二、UIViewController 生命周期

视图控制器是管理 UIView 的核心,其生命周期围绕视图的创建、显示、隐藏、销毁展开,是 iOS 开发中最常接触的生命周期。

核心方法(按执行顺序)

swift 复制代码
import UIKit

class ViewController: UIViewController {

    // 1. 初始化(创建VC对象)
    init?(coder: NSCoder) {
        super.init(coder: coder)
        print("1. 初始化 - init")
        // 初始化非UI相关的属性
    }

    // 2. 加载视图(首次访问view属性时触发)
    override func loadView() {
        super.loadView()
        print("2. 加载视图 - loadView")
        // 手动创建view(若不重写,系统会加载storyboard/xib的view)
        self.view = UIView(frame: UIScreen.main.bounds)
        self.view.backgroundColor = .white
    }

    // 3. 视图加载完成(view已创建完成)
    override func viewDidLoad() {
        super.viewDidLoad()
        print("3. 视图加载完成 - viewDidLoad")
        // 初始化UI控件、绑定数据、添加监听(只执行一次)
    }

    // 4. 视图即将布局子视图(view的bounds变化时触发,如旋转屏幕)
    override func viewWillLayoutSubviews() {
        super.viewWillLayoutSubviews()
        print("4. 视图即将布局子视图 - viewWillLayoutSubviews")
        // 调整控件布局(执行多次)
    }

    // 5. 视图已布局子视图
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        print("5. 视图已布局子视图 - viewDidLayoutSubviews")
        // 获取控件最终的frame(执行多次)
    }

    // 6. 视图即将显示在屏幕上(每次显示都触发,如push/pop后重新显示)
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        print("6. 视图即将显示 - viewWillAppear")
        // 刷新数据、开始动画、注册通知等
    }

    // 7. 视图已显示在屏幕上
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        print("7. 视图已显示 - viewDidAppear")
        // 启动定时器、请求网络数据、播放视频等
    }

    // 8. 视图即将从屏幕上消失
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        print("8. 视图即将消失 - viewWillDisappear")
        // 暂停动画、移除通知、保存数据等
    }

    // 9. 视图已从屏幕上消失
    override func viewDidDisappear(_ animated: Bool) {
        super.viewDidDisappear(animated)
        print("9. 视图已消失 - viewDidDisappear")
        // 释放不必要的资源(如图片缓存)
    }

    // 10. 内存警告(系统内存不足时触发)
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        print("10. 内存警告 - didReceiveMemoryWarning")
        // 释放缓存、非必要的视图等
    }

    // 11. 视图控制器销毁(deinit)
    deinit {
        print("11. 视图控制器销毁 - deinit")
        // 最终的资源释放(如移除监听、取消网络请求)
    }
}

关键说明

  • 核心流程:初始化 → 加载视图 → 视图加载完成 → 布局子视图 → 即将显示 → 已显示 → 即将消失 → 已消失 → 销毁。
  • viewDidLoad :只执行一次,适合做一次性初始化;viewWillAppear/viewDidAppear:每次显示都执行,适合刷新动态数据。
  • 内存警告didReceiveMemoryWarning中需主动释放非必要资源,避免 App 被系统杀死。
  • deinit:只有当 VC 的引用计数为 0 时才会触发,需确保无循环引用(如闭包未捕获 self 为 weak/unowned)。

三、UIView 生命周期

UIView 的生命周期依附于视图控制器,核心是 "创建 - 布局 - 绘制 - 销毁",重点关注布局和绘制相关方法。

核心阶段与方法

swift 复制代码
import UIKit

class CustomView: UIView {

    // 1. 初始化(创建View)
    override init(frame: CGRect) {
        super.init(frame: frame)
        print("1. View初始化 - init(frame:)")
        // 设置默认属性(如背景色、圆角)
        self.backgroundColor = .lightGray
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        print("1. View初始化 - init(coder:)")
    }

    // 2. 准备布局(iOS 6+,替代autoresizingMask)
    override func prepareForLayout() {
        super.prepareForLayout()
        print("2. 准备布局 - prepareForLayout")
        // 布局前的准备工作(如设置约束优先级)
    }

    // 3. 布局子视图(bounds变化时触发,如frame、center修改)
    override func layoutSubviews() {
        super.layoutSubviews()
        print("3. 布局子视图 - layoutSubviews")
        // 手动调整子视图frame(若不用AutoLayout)
        for subview in self.subviews {
            subview.center = self.center
        }
    }

    // 4. 绘制内容(首次显示/setNeedsDisplay()触发)
    override func draw(_ rect: CGRect) {
        super.draw(rect)
        print("4. 绘制内容 - draw(_:)")
        // 手动绘制图形(如绘制线条、文字)
        let context = UIGraphicsGetCurrentContext()
        context?.setStrokeColor(UIColor.red.cgColor)
        context?.stroke(CGRect(x: 10, y: 10, width: 100, height: 100))
    }

    // 5. 即将添加到父视图
    override func willMove(toSuperview newSuperview: UIView?) {
        super.willMove(toSuperview: newSuperview)
        print("5. 即将添加到父视图 - willMove(toSuperview:)")
        // 父视图变化前的处理
    }

    // 6. 已添加到父视图
    override func didMoveToSuperview() {
        super.didMoveToSuperview()
        print("6. 已添加到父视图 - didMoveToSuperview")
        // 父视图变化后的处理(如根据父视图调整自身大小)
    }

    // 7. 即将添加到窗口
    override func willMove(toWindow newWindow: UIWindow?) {
        super.willMove(toWindow: newWindow)
        print("7. 即将添加到窗口 - willMove(toWindow:)")
    }

    // 8. 已添加到窗口
    override func didMoveToWindow() {
        super.didMoveToWindow()
        print("8. 已添加到窗口 - didMoveToWindow")
        // 只有添加到window后,View才会真正显示在屏幕上
    }

    // 9. 销毁(deinit)
    deinit {
        print("9. View销毁 - deinit")
        // 释放View相关资源(如移除子视图、取消动画)
    }
}

关键说明

  • layoutSubviews:最常用的方法,每次 View 的尺寸变化都会触发,适合手动调整子视图布局(若使用 AutoLayout,系统会自动处理,无需重写)。
  • draw(_:) :仅在需要手动绘制内容时重写,避免在其中做耗时操作(会影响渲染性能);调用setNeedsDisplay()可触发重新绘制。
  • Window 关联 :View 只有添加到UIWindow(应用的主窗口)后,才会被渲染并显示在屏幕上;didMoveToWindow是 View 真正 "可见" 的标志。
  • 销毁 :当 View 从父视图移除且无强引用时,deinit触发,需确保子视图也被正确释放。

总结

  1. 应用生命周期 :全局层面,管理 App 从启动到终止的状态,核心是UIApplicationDelegate的代理方法,关注前台 / 后台切换和资源保存。
  2. 视图控制器生命周期 :页面层面,核心是viewDidLoad(一次性初始化)、viewWillAppear(每次显示刷新)、deinit(资源释放),是业务逻辑的主要载体。
  3. 视图生命周期 :控件层面,依附于 VC,核心是layoutSubviews(布局)和draw(_:)(绘制),关注控件尺寸调整和视觉渲染。

三者的关联:App 启动后创建根 VC → VC 创建并加载 View → View 添加到 Window 显示 → App 进入前台活跃状态;App 进入后台时,VC 的 View 会被隐藏,资源可按需释放。

相关推荐
毛发浓密的女猴子1 天前
SSE Connect 数据解析详解
ios
JAVA+C语言1 天前
iOS App小组件(Widget)显示LottieFiles动画
ios
2501_915921431 天前
如何将 iOS 应用的 IPA 文件安装到手机进行测试
android·ios·智能手机·小程序·uni-app·iphone·webview
2501_916008891 天前
不连 Xcode,也能把 iPhone App 的实时日志看清楚
android·ios·小程序·https·uni-app·iphone·webview
小CC吃豆子1 天前
uni-app 上架 iOS 时常见的审核被拒原因有哪些?
ios·uni-app
TheNextByte11 天前
如何将 Infinix 手机中的联系人传输到 iPhone
ios·智能手机·iphone
2501_915921432 天前
iOS App 中 SSL Pinning 场景下代理抓包失效的原因
android·网络协议·ios·小程序·uni-app·iphone·ssl
Swift社区2 天前
Flutter / RN / iOS 的 UI 渲染机制,本质差异在哪里?
flutter·ui·ios