ViewController Lifecycle trong iOS: khái niệm chính, giai đoạn và phương thức

Tác giả: IT Sectr Đã đăng: 2026-03-05 Thời gian đọc: 9 phút

ViewController Lifecycle là trình tự các phương thức mà UIKit tự động gọi khi quản lý màn hình trong iOS. Theo Tài liệu Apple, mỗi UIViewController trải qua một tập hợp các trạng thái có thể dự đoán: từ tạo View đến khi xuất hiện và ẩn đi. Hiểu thứ tự và mục đích của các phương thức này là điều kiện cần thiết cho hoạt động ổn định của ứng dụng iOS.

Các điểm chính

  • ViewController Lifecycle bao gồm sáu phương thức UIViewController được UIKit gọi theo thứ tự nghiêm ngặt
  • loadView tạo hệ phân cấp View nếu bạn không dùng Storyboard
  • viewDidLoad được gọi một lần và phù hợp để thiết lập màn hình ban đầu
  • viewWillAppearviewDidAppear kích hoạt mỗi lần xuất hiện
  • viewWillDisappearviewDidDisappear — để lưu trạng thái và dọn dẹp

ViewController Lifecycle là gì

ViewController Lifecycle là tập hợp các phương thức mà UIViewController nhận từ UIKit trong suốt vòng đời của nó. Mỗi màn hình trong ứng dụng iOS tuần tự trải qua các giai đoạn tạo, tải View, xuất hiện trên màn hình, ẩn đi và giải phóng bộ nhớ. UIKit tự động gọi các phương thức tương ứng ở mỗi giai đoạn và nhà phát triển ghi đè chúng để thêm logic riêng.

Kiến trúc UIViewController là nền tảng của UIKit và vẫn còn phù hợp ngay cả trong kỷ nguyên SwiftUI — nhiều dự án vẫn sử dụng cách tiếp cận cổ điển hoặc kiến trúc kết hợp. Hiểu Lifecycle cho phép bạn dự đoán khi nào subviews có sẵn, khi nào an toàn để sửa đổi bố cục và thao tác nào cần thực hiện khi màn hình xuất hiện hoặc ẩn đi.

Mỗi phương thức của vòng đời có một mục đích cụ thể: một số được gọi một lần trong toàn bộ vòng đời của bộ điều khiển, một số khác — mỗi lần xuất hiện hoặc ẩn đi. Trộn lẫn logic giữa các phương thức dẫn đến lỗi khó tìm: rò rỉ bộ nhớ, cập nhật dữ liệu không chính xác và yêu cầu mạng không cần thiết.

Chu trình đầy đủ các phương thức UIViewController

Sáu phương thức tạo thành vòng đời hoàn chỉnh của UIViewController. Thứ tự gọi là cố định và không phụ thuộc vào phương thức điều hướng — push, present hay unwind segue đều tuân theo cùng một lịch trình.

loadView — tạo View gốc

loadView là phương thức đầu tiên của chu trình, được gọi khi View của bộ điều khiển chưa tồn tại. Nếu bạn sử dụng Storyboard, UIKit tự động tải View từ tệp xib. Khi tạo giao diện bằng mã, bạn ghi đè phương thức này bằng cách gán View gốc thủ công. Trong hầu hết các dự án, loadView không được động đến — công việc được thực hiện trong viewDidLoad.

Ghi đè loadView chỉ cần thiết trong các trường hợp cụ thể: khi toàn bộ giao diện được tạo bằng mã không có Storyboard, hoặc khi View gốc cần thuộc lớp không chuẩn. Apple khuyên không nên gọi super.loadView khi ghi đè — bạn hoàn toàn chịu trách nhiệm tạo View.

swift
override func loadView() {
    view = UIView()
    view.backgroundColor = .white
}

viewDidLoad — khởi tạo một lần

viewDidLoad là phương thức được sử dụng nhiều nhất trong chu trình. Nó được gọi một lần sau khi View được tải vào bộ nhớ nhưng chưa được hiển thị trên màn hình. Tại đây, bạn cấu hình subviews, điền dữ liệu vào bảng, đăng ký ô và đăng ký nhận thông báo kéo dài suốt vòng đời của bộ điều khiển.

Một tính năng quan trọng: viewDidLoad không được gọi lại khi màn hình xuất hiện lại. Nếu bạn cần cập nhật dữ liệu mỗi khi màn hình xuất hiện — hãy sử dụng viewWillAppear. Chỉ đặt các thao tác một lần trong viewDidLoad cần thiết cho cấu hình cơ bản.

viewWillAppear — chuẩn bị trước khi hiển thị

viewWillAppear được gọi mỗi lần ngay trước khi View hiển thị cho người dùng. Phương thức này nhận tham số animated cho biết việc xuất hiện có được tạo hiệu ứng hay không. Tại đây, bạn cập nhật dữ liệu, tải lại bảng, cấu hình NavigationBar và ẩn hoặc hiện các phần tử tùy theo trạng thái ứng dụng.

Sử dụng viewWillAppear để đồng bộ hóa trạng thái giữa các màn hình: nếu người dùng có thể đã thay đổi dữ liệu trên màn hình trước đó, phương thức này là nơi thích hợp để cập nhật giao diện. Mỗi lần gọi viewWillAppear đều diễn ra trước khi màn hình xuất hiện, ngay cả khi quay lại từ bộ điều khiển con.

viewDidAppear — màn hình hiển thị hoàn toàn

viewDidAppear thông báo rằng View đã xuất hiện hoàn toàn trên màn hình và tất cả hiệu ứng chuyển tiếp đã hoàn tất. Tại thời điểm này, màn hình sẵn sàng cho tương tác — người dùng thấy giao diện đầy đủ và có thể tương tác với nó. Phương thức này phù hợp để bắt đầu hiệu ứng nên diễn ra sau khi xuất hiện, khởi động bộ đếm thời gian và theo dõi số lần hiển thị phân tích.

Không giống như viewWillAppear, viewDidAppear đảm bảo màn hình không chỉ hiển thị mà còn được kết xuất đầy đủ. Nếu bạn bắt đầu hiệu ứng trong viewWillAppear, một số khung hình có thể bị bỏ qua vì UIKit chưa hoàn tất chuyển tiếp. Để có hiệu ứng mượt mà, hãy sử dụng viewDidAppear.

viewWillDisappear — chuẩn bị ẩn

viewWillDisappear được gọi trước khi View biến mất khỏi màn hình — khi chuyển sang bộ điều khiển khác, đóng cửa sổ phương thức hoặc tạm dừng ứng dụng. Đây là nơi thích hợp để lưu trạng thái, hủy đăng ký thông báo, dừng các tiến trình đang hoạt động và giải phóng tài nguyên không cần thiết khi màn hình không hiển thị.

Điều quan trọng cần nhớ: viewWillDisappear không đảm bảo rằng View cuối cùng sẽ biến mất — cử chỉ có thể bị hủy. Do đó, hãy lưu dữ liệu quan trọng trong viewDidDisappear, phương thức chỉ được gọi sau khi thực sự biến mất.

viewDidDisappear — màn hình đã ẩn

viewDidDisappear hoàn thành chu trình xuất hiện và biến mất. Nó được gọi sau khi View đã bị ẩn khỏi màn hình. Trong phương thức này, hiệu ứng cuối cùng được dừng lại, các đối tượng tạm thời bị xóa và việc lưu dữ liệu bắt đầu trong viewWillDisappear được xác nhận.

Phương thức này cũng diễn ra trước deinit của bộ điều khiển — nếu UIViewController của bạn bị hủy, viewDidDisappear sẽ là phương thức Lifecycle cuối cùng trước khi deinit được gọi. Sử dụng nó để dọn dẹp cuối cùng trước khi đối tượng bị hủy.

Khi nào mỗi phương thức được gọi

Trình tự các lần gọi phụ thuộc vào cách màn hình xuất hiện: lần đầu tiên, khi quay lại hoặc khi được trình bày theo phương thức. Hãy xem xét ba kịch bản chính từ góc nhìn của UIKit.

Thứ tự khi mở lần đầu

Khi màn hình xuất hiện lần đầu tiên, UIKit trải qua chu trình tạo đầy đủ: loadView được gọi, sau đó viewDidLoad, sau đó hiệu ứng xuất hiện bắt đầu. Trong quá trình hiệu ứng, viewWillAppear được gọi và sau khi hoàn tất — viewDidAppear. Đây là kịch bản duy nhất mà tất cả các phương thức từ loadView đến viewDidAppear kích hoạt tuần tự.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    print("viewDidLoad — View đã tải vào bộ nhớ")
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    print("viewWillAppear — Sắp xuất hiện")
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    print("viewDidAppear — Màn hình hiển thị hoàn toàn")
}

Thứ tự khi quay lại

Khi người dùng quay lại màn hình trước đó, UIKit không gọi lại viewDidLoad — View đã được tải vào bộ nhớ. Thay vào đó, chỉ viewWillAppear và viewDidAppear được gọi trên màn hình quay lại, và trên màn hình hiện tại — viewWillDisappear và viewDidDisappear. loadView và viewDidLoad được bỏ qua vì màn hình đã tồn tại trong ngăn xếp điều hướng.

Trường hợp đặc biệt với present và dismiss

Trình bày phương thức tuân theo cùng quy tắc: bộ điều khiển mới trải qua chu trình đầy đủ ở lần xuất hiện đầu tiên, trong khi bộ điều khiển hiện tại nhận viewWillDisappear và viewDidDisappear. Khi dismiss, thứ tự đảo ngược: bộ điều khiển quay lại nhận viewWillAppear và viewDidAppear một lần nữa, trong khi bộ điều khiển bị loại bỏ nhận các phương thức cuối cùng. Hành vi này là thống nhất cho tất cả các loại chuyển tiếp trong UIKit.

Các kịch bản sử dụng thực tế

Hãy xem xét bốn kịch bản chính nơi hiểu Lifecycle ảnh hưởng trực tiếp đến chất lượng mã và trải nghiệm người dùng. Cho mỗi kịch bản, chúng tôi cung cấp ví dụ với các khuyến nghị.

Khởi tạo dữ liệu trong viewDidLoad

viewDidLoad là nơi thiết lập ban đầu không phụ thuộc vào khả năng hiển thị màn hình. Tại đây bạn cấu hình collectionView, đăng ký tệp nib cho các ô, tạo nguồn dữ liệu và bố cục. Nếu bạn đang tải dữ liệu từ mạng, trong viewDidLoad tốt hơn chỉ nên khởi tạo yêu cầu và cập nhật UI trong viewWillAppear khi màn hình sẵn sàng hiển thị.

swift
override func viewDidLoad() {
    super.viewDidLoad()
    tableView.register(
        MyCell.self,
        forCellReuseIdentifier: MyCell.identifier
    )
    viewModel.loadInitialData()
}

Cập nhật nội dung trong viewWillAppear

Sử dụng viewWillAppear để đồng bộ hóa dữ liệu mỗi khi màn hình xuất hiện. Ví dụ: nếu người dùng có thể đã thay đổi cài đặt trên màn hình trước đó, tại đây bạn cập nhật các giá trị hiển thị, tải lại bảng và điều chỉnh trạng thái NavigationBar. Điều này đảm bảo màn hình luôn hiển thị dữ liệu cập nhật trong mọi kịch bản điều hướng.

swift
override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)
    tableView.reloadData()
    navigationController?.setNavigationBarHidden(false, animated: animated)
}

Phân tích và hiệu ứng trong viewDidAppear

viewDidAppear là lý tưởng để bắt đầu hiệu ứng nên diễn ra sau khi người dùng đã nhìn thấy màn hình. Tại đây bạn cũng gửi sự kiện phân tích: xem màn hình, bắt đầu onboarding hoặc phát video. Bắt đầu hiệu ứng trước khi chuyển tiếp hoàn tất dẫn đến giao diện giật lag — UIKit không có đủ thời gian để chuẩn bị số lượng khung hình cần thiết.

Lưu trạng thái trong viewWillDisappear

Trong viewWillDisappear, bạn lưu bản nháp, dừng bộ đếm thời gian và hủy đăng ký khỏi NotificationCenter. Đây là khoảnh khắc cuối cùng màn hình vẫn hiển thị và có thể truy cập cho các thao tác yêu cầu ngữ cảnh người dùng. Đối với dữ liệu quan trọng, hãy sử dụng thêm viewDidDisappear như một biện pháp bảo vệ chống lại các cử chỉ bị hủy.

Lỗi thường gặp khi làm việc với Lifecycle

Sử dụng sai các phương thức vòng đời là một trong những nguồn lỗi phổ biến nhất trong ứng dụng iOS. Hãy xem xét các lỗi chính mà nhà phát triển mắc phải ở các giai đoạn khác nhau khi làm việc với UIViewController.

Lỗi thứ nhất — tạo subviews trong init hoặc loadView khi sử dụng Storyboard. Nếu bạn đang sử dụng Interface Builder, đừng ghi đè loadView không cần thiết. Tạo View trong loadView khi có storyboard dẫn đến việc bỏ qua tệp xib và màn hình trống.

Lỗi thứ hai — đăng ký nhận thông báo bàn phím trong viewDidLoad mà không hủy đăng ký. Nếu bạn đã đăng ký UIResponder.keyboardWillShowNotification nhưng không hủy đăng ký khi ẩn màn hình, khối sẽ tiếp tục được gọi ngay cả sau khi deinit của bộ điều khiển — đây là rò rỉ bộ nhớ có khả năng làm ứng dụng bị treo.

Lỗi thứ ba — bộ đếm thời gian và yêu cầu mạng bắt đầu trước khi màn hình xuất hiện. Tải hình ảnh hoặc thực hiện hiệu ứng khi View chưa hiển thị là lãng phí tài nguyên. Di chuyển các bản cập nhật trực quan sang viewWillAppear hoặc viewDidAppear.

Lỗi thứ tư — chỉ lưu dữ liệu trong viewWillDisappear. Với cử chỉ pop tương tác, người dùng có thể bắt đầu vuốt và hủy nó — phương thức đã được gọi nhưng màn hình không biến mất. Hãy sao chép việc lưu quan trọng trong viewDidDisappear hoặc trong trình xử lý applicationDidEnterBackground.

Câu hỏi thường gặp

ViewDidLoad được gọi bao nhiêu lần trong vòng đời của bộ điều khiển?

Một lần — sau khi View được tải vào bộ nhớ. Khi màn hình xuất hiện lại, viewDidLoad không được gọi. Nếu cần tạo lại View, bộ điều khiển phải bị hủy và tạo mới.

Điều gì xảy ra nếu không gọi super trong viewDidLoad?

UIKit yêu cầu gọi super.viewDidLoad để vòng đời hoạt động chính xác. Nếu không, có thể xảy ra vấn đề với cập nhật bố cục và xử lý chuyển tiếp. Luôn gọi super trước tiên bên trong phương thức.

Tôi có thể sử dụng Storyboard và loadView bằng mã cùng lúc không?

Không được khuyến nghị. Nếu bộ điều khiển được khởi tạo từ Storyboard, UIKit tự động tải View từ xib. Ghi đè loadView hủy quá trình này và storyboard của bạn sẽ bị bỏ qua.

Làm thế nào để hủy đăng ký khỏi NotificationCenter đúng cách?

Đăng ký trong viewDidLoad hoặc viewWillAppear và hủy đăng ký trong viewWillDisappear hoặc viewDidDisappear, sử dụng tham chiếu yếu đến self để tránh rò rỉ bộ nhớ với closure.

Tại sao viewDidDisappear không được gọi khi force quit?

Force quit giết tiến trình đột ngột — UIKit không có thời gian để gọi các phương thức Lifecycle. Để lưu dữ liệu, hãy sử dụng thông báo UIApplication.willTerminateNotification trong AppDelegate.

Tóm tắt

  • ViewController Lifecycle bao gồm sáu phương thức được UIKit gọi theo thứ tự cố định
  • loadViewviewDidLoad kích hoạt một lần khi bộ điều khiển được tạo
  • viewWillAppearviewDidAppear được gọi mỗi khi màn hình xuất hiện
  • viewWillDisappearviewDidDisappear — mỗi khi ẩn đi
  • Mỗi phương thức có mục đích cụ thể — trộn logic dẫn đến lỗi
  • Đăng ký thông báo luôn phải cân bằng với hủy đăng ký trong phương thức tương ứng
  • Sử dụng viewDidAppear cho hiệu ứng và phân tích, và viewWillDisappear để lưu trạng thái

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm