Swift中View和ViewController的生命周期
View 和 ViewController 生命周期
1. ViewController 生命周期
完整生命周期流程
text
init → loadView → viewDidLoad → viewWillAppear → viewWillLayoutSubviews → viewDidLayoutSubviews → viewDidAppear → viewWillDisappear → viewDidDisappear → deinit
详细方法说明
① 初始化阶段
swift
// 1. 初始化
override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)print("init with nibName")
}required init?(coder: NSCoder) {super.init(coder: coder)print("init with coder")
}// 2. 加载视图
override func loadView() {// 创建 view hierarchysuper.loadView()print("loadView")
}
② 视图加载完成
swift
override func viewDidLoad() {super.viewDidLoad()print("viewDidLoad")// 适合做一次性设置setupUI()setupData()addObservers()
}
③ 视图显示前后
swift
override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)print("viewWillAppear")// 每次显示前更新数据refreshData()startAnimation()
}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)print("viewDidAppear")// 开始耗时操作startNetworkRequest()// 开始监听通知NotificationCenter.default.addObserver(...)
}
④ 视图布局
swift
override func viewWillLayoutSubviews() {super.viewWillLayoutSubviews()print("viewWillLayoutSubviews")// 布局前调整
}override func viewDidLayoutSubviews() {super.viewDidLayoutSubviews()print("viewDidLayoutSubviews")// 基于最终布局的调整updateViewFrames()
}
⑤ 视图消失
swift
override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)print("viewWillDisappear")// 停止动画stopAnimation()// 保存数据saveCurrentState()
}override func viewDidDisappear(_ animated: Bool) {super.viewDidDisappear(animated)print("viewDidDisappear")// 清理资源NotificationCenter.default.removeObserver(self)cancelNetworkRequests()
}
⑥ 销毁
swift
deinit {print("deinit")// 最终清理cleanupResources()
}
2. View 生命周期
UIView 生命周期方法
swift
class CustomView: UIView {// 1. 初始化override init(frame: CGRect) {super.init(frame: frame)setupView()}required init?(coder: NSCoder) {super.init(coder: coder)setupView()}// 2. 将要添加到窗口override func willMove(toWindow newWindow: UIWindow?) {super.willMove(toWindow: newWindow)print("willMove toWindow: \(newWindow)")}// 3. 已经添加到父视图override func didMoveToSuperview() {super.didMoveToSuperview()print("didMoveToSuperview: \(superview)")}// 4. 布局override func layoutSubviews() {super.layoutSubviews()print("layoutSubviews")// 自定义布局逻辑}// 5. 绘制override func draw(_ rect: CGRect) {super.draw(rect)print("draw")// 自定义绘制}// 6. 从窗口移除override func willMove(toSuperview newSuperview: UIView?) {super.willMove(toSuperview: newSuperview)print("willMove toSuperview: \(newSuperview)")}// 7. 从父视图移除override func removeFromSuperview() {super.removeFromSuperview()print("removeFromSuperview")}
}
3. 生命周期使用场景
数据加载时机
swift
class DataViewController: UIViewController {// ✅ viewDidLoad - 一次性数据override func viewDidLoad() {super.viewDidLoad()loadStaticData() // 静态数据setupCoreComponents() // 核心组件}// ✅ viewWillAppear - 动态数据override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)refreshDynamicData() // 动态数据刷新updateUIState() // UI状态更新}// ❌ 不要在 init 中访问 viewoverride init(nibName: String?, bundle: Bundle?) {super.init(nibName: nibName, bundle: bundle)// self.view // 崩溃!view 还未创建}
}
动画处理时机
swift
class AnimationViewController: UIViewController {// ✅ viewDidAppear - 开始动画override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)startEntranceAnimation()}// ✅ viewWillDisappear - 停止动画override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)stopAllAnimations()}
}
内存管理
swift
class MemoryManagementViewController: UIViewController {var heavyObject: HeavyObject?var notificationObserver: NSObjectProtocol?// ✅ viewDidLoad - 创建重量级对象override func viewDidLoad() {super.viewDidLoad()heavyObject = HeavyObject()// 注册通知notificationObserver = NotificationCenter.default.addObserver(forName: .customNotification,object: nil,queue: .main) { _ inself.handleNotification()}}// ✅ deinit - 清理资源deinit {// 移除通知if let observer = notificationObserver {NotificationCenter.default.removeObserver(observer)}// 释放重量级对象heavyObject = nil}
}
4. 特殊场景的生命周期
模态展示的 ViewController
swift
class ModalViewController: UIViewController {override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)print("Modal will appear")}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)print("Modal did appear")}@IBAction func closeTapped() {dismiss(animated: true) {print("Modal dismissed completion")}}
}
导航控制器中的生命周期
swift
class NavigationExampleViewController: UIViewController {override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)print("在导航栈中显示")}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)if isMovingFromParent {print("从导航栈弹出")} else if isBeingDismissed {print("被模态关闭")}}
}
5. 实际项目中的最佳实践
代码组织模板
swift
class WellStructuredViewController: UIViewController {// MARK: - Lifecycleoverride func viewDidLoad() {super.viewDidLoad()setupUI()setupConstraints()setupBindings()}override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)loadData()updateNavigationBar()}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)startAnalyticsTracking()}override func viewWillDisappear(_ animated: Bool) {super.viewWillDisappear(animated)saveUserProgress()}override func viewDidDisappear(_ animated: Bool) {super.viewDidDisappear(animated)stopAnalyticsTracking()}deinit {cleanupResources()}// MARK: - UI Setupprivate func setupUI() {// 创建和配置 UI 组件}private func setupConstraints() {// 设置自动布局约束}// MARK: - Dataprivate func setupBindings() {// 设置数据绑定}private func loadData() {// 加载数据}
}
常见错误避免
swift
class ProblematicViewController: UIViewController {// ❌ 错误:在 init 中访问 viewoverride init(nibName: String?, bundle: Bundle?) {super.init(nibName: nibName, bundle: bundle)// self.view.backgroundColor = .red // 崩溃!}// ❌ 错误:重复添加观察者override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)NotificationCenter.default.addObserver(self, selector: #selector(handleNotif), name: .test, object: nil)// 每次出现都添加,会导致多次调用}// ✅ 正确:在 viewDidLoad 中添加一次override func viewDidLoad() {super.viewDidLoad()NotificationCenter.default.addObserver(self, selector: #selector(handleNotif), name: .test, object: nil)}
}
6. 调试技巧
打印生命周期
swift
class DebugViewController: UIViewController {override func viewDidLoad() {super.viewDidLoad()print("🎯 \(type(of: self)) - viewDidLoad")}override func viewWillAppear(_ animated: Bool) {super.viewWillAppear(animated)print("🎯 \(type(of: self)) - viewWillAppear")}override func viewDidAppear(_ animated: Bool) {super.viewDidAppear(animated)print("🎯 \(type(of: self)) - viewDidAppear")}deinit {print("🎯 \(type(of: self)) - deinit")}
}
-------------------------------------------
