viewWillDisappear trong iOS — bản chất của phương thức và cách sử dụng đúng

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

viewWillDisappear là một phương thức của UIViewController mà UIKit gọi ngay trước khi màn hình bắt đầu biến mất khỏi màn hình của người dùng. Theo Apple Developer Documentation, phương thức này nhận tham số animated và được kích hoạt khi push, pop, present, dismiss và chuyển tab. viewWillDisappear là nơi chính để lưu trạng thái và dọn dẹp tài nguyên một cách chính xác.

Các điểm chính

  • viewWillDisappear được gọi trước mỗi lần màn hình biến mất
  • Được sử dụng để lưu trạng thái của bản nháp và dữ liệu tạm thời
  • Hủy đăng ký khỏi NotificationCenter và KVO là nhiệm vụ bắt buộc trong phương thức này
  • Phương thức có thể được gọi khi cử chỉ bị hủy — nhân đôi dữ liệu trong viewDidDisappear
  • super.viewWillDisappear là bắt buộc để điều hướng chính xác

viewWillDisappear là gì

viewWillDisappear là một phương thức của UIViewController mà UIKit gọi ngay trước khi View của bộ điều khiển bắt đầu biến mất khỏi màn hình. Tại thời điểm này, màn hình vẫn hiển thị với người dùng, nhưng quá trình chuyển tiếp đã được bắt đầu: NavigationController bắt đầu hoạt ảnh push/pop, chế độ xem phương thức bắt đầu đóng, hoặc TabBar bắt đầu chuyển sang tab khác. Nhà phát triển ghi đè phương thức này để thực hiện các thao tác yêu cầu màn hình vẫn có thể truy cập được nhưng đang chuẩn bị ẩn.

Không giống như viewDidDisappear, được kích hoạt sau khi màn hình bị ẩn, viewWillDisappear cung cấp cơ hội cuối cùng để lưu dữ liệu và giải phóng tài nguyên trong khi người dùng vẫn có thể nhìn thấy giao diện. Điều này cực kỳ quan trọng đối với UX — lưu bản nháp hoặc dừng bộ đếm giờ phải xảy ra trước khi người dùng chuyển sang màn hình khác.

Phương thức chấp nhận tham số animated, cho biết liệu sự biến mất có được hoạt ảnh hóa hay không. true có nghĩa là UIKit đang thực hiện chuyển tiếp có hoạt ảnh, false có nghĩa là màn hình biến mất ngay lập tức, ví dụ trong quá trình dismiss không có hoạt ảnh hoặc xóa theo chương trình khỏi hệ phân cấp.

Khi nào viewWillDisappear được gọi

viewWillDisappear được gọi trong tất cả các kịch bản khi màn hình hiện tại không còn hoạt động. Hãy xem xét các trường hợp chính cụ thể cho phát triển iOS.

Khi push màn hình mới

Khi UINavigationController thực hiện push một bộ điều khiển mới, viewWillDisappear được gọi trên bộ điều khiển hiện tại khi bắt đầu hoạt ảnh chuyển tiếp. Tại thời điểm này, màn hình hiện tại vẫn hiển thị bên dưới bộ điều khiển mới trượt lên trên nó. Đây là kịch bản tiêu chuẩn mà viewWillDisappear kích hoạt với animated = true.

Khi pop màn hình hiện tại

Khi người dùng nhấn nút quay lại hoặc thực hiện thao tác vuốt tương tác để quay lại, viewWillDisappear được gọi trên bộ điều khiển hiện tại. Với cử chỉ tương tác, lời gọi này có thể bị hủy nếu người dùng đổi ý và đưa màn hình trở lại vị trí ban đầu. Đây là một tính năng quan trọng cần cân nhắc khi thiết kế việc lưu trạng thái.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    saveDraftData()
    NotificationCenter.default.removeObserver(self)
}

Khi dismiss bộ điều khiển

Khi đóng chế độ xem phương thức, viewWillDisappear được gọi trên bộ điều khiển đang đóng khi bắt đầu hoạt ảnh dismiss. Tại thời điểm này, bạn có thể truyền kết quả trở lại thông qua ủy quyền hoặc bao đóng, vì bộ điều khiển đã trình bày chế độ xem phương thức vẫn chưa giành lại quyền điều khiển.

Khi chuyển tab TabBar

UITabBarController gọi viewWillDisappear trên bộ điều khiển của tab bị rời ngay sau khi người dùng chạm vào tab khác. Nếu tab hiện tại có các tiến trình đang hoạt động — phát lại phương tiện, tải tệp xuống, bộ đếm giờ — chúng nên được tạm dừng hoặc dừng ở đây.

Các tác vụ thực tế trong viewWillDisappear

viewWillDisappear giải quyết các tác vụ cụ thể liên quan đến quản lý tài nguyên và trạng thái. Hãy xem xét các kịch bản chính với các ví dụ mã.

Lưu dữ liệu người dùng

Nhiệm vụ quan trọng nhất của viewWillDisappear là lưu dữ liệu mà người dùng đã nhập hoặc sửa đổi trên màn hình hiện tại. Bản nháp tin nhắn, trường biểu mẫu đã chỉnh sửa, cài đặt đã chọn — tất cả những thứ này phải được lưu trước khi màn hình biến mất. Sử dụng Core Data, UserDefaults hoặc bộ nhớ tập tin để duy trì.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    guard hasUnsavedChanges else { return }
    draftStorage.save(currentDraft)
}

Hủy đăng ký khỏi thông báo

Các nhà xuất bản NotificationCenter, KVO và Combine mà bạn đã đăng ký trong viewWillAppear hoặc viewDidLoad phải được hủy trong viewWillDisappear. Nếu không, các thông báo sẽ đến màn hình đã ẩn, gây ra các bản cập nhật giao diện mà người dùng không nhìn thấy, hoặc tệ hơn — sự cố do truy cập vào các đối tượng đã được phân bổ.

Dừng hoạt ảnh và bộ đếm giờ

Các hoạt ảnh UIView được bắt đầu trong viewDidAppear và các bộ đếm giờ chạy qua Timer hoặc DispatchSource phải được dừng trong viewWillDisappear. Các hoạt ảnh tiếp diễn trên màn hình đã ẩn lãng phí GPU và pin mà không có lợi ích gì cho người dùng. Hãy dừng chúng một cách rõ ràng bằng cách gọi invalidate trên các bộ đếm giờ và removeAllAnimations trên các lớp.

swift
override func viewWillDisappear(_ animated: Bool) {
    super.viewWillDisappear(animated)
    countdownTimer?.invalidate()
    countdownTimer = nil
    loadingIndicator.layer.removeAllAnimations()
}

Truyền dữ liệu trở lại

Nếu một bộ điều khiển được mở để lấy kết quả — chọn mục, nhập văn bản, xác nhận hành động — viewWillDisappear là thời điểm cuối cùng mà bộ điều khiển ban đầu vẫn tồn tại trong ngăn xếp và có thể nhận dữ liệu. Gọi ủy quyền hoặc bao đóng trước khi deinit được gọi.

Chiến lược lưu trạng thái

Lưu trạng thái đáng tin cậy là một trong những nhiệm vụ khó khăn nhất trong phát triển iOS. viewWillDisappear là một yếu tố quan trọng nhưng không phải là yếu tố duy nhất của chiến lược. Hãy xem xét một cách tiếp cận toàn diện.

Cấp độ 1 — lưu trong viewWillDisappear. Lưu nhanh dữ liệu nhẹ có sẵn ngay khi quay lại. Phù hợp cho trạng thái giao diện: vị trí cuộn, phân đoạn đã chọn, văn bản trong trường nhập. Vấn đề: khi cử chỉ pop tương tác bị hủy, việc lưu vẫn diễn ra mặc dù người dùng ở lại trên màn hình — dữ liệu bị ghi đè một cách không cần thiết.

Cấp độ 2 — lưu trong viewDidDisappear. Nhân đôi việc lưu từ cấp độ đầu tiên nhưng chỉ kích hoạt sau khi màn hình được đảm bảo ẩn. Đây là biện pháp bảo vệ chống các cử chỉ bị hủy. Tuy nhiên, nếu bạn đã hủy đăng ký thông báo trong viewWillDisappear, viewDidDisappear có thể không truy cập được một số dữ liệu.

Cấp độ 3 — lưu thông qua thông báo ứng dụng. UIApplication.willResignActiveNotification và UIApplication.didEnterBackgroundNotification bắt việc đưa ứng dụng ra nền. Nếu người dùng thu nhỏ ứng dụng, viewWillDisappear có thể chưa được gọi — nhưng việc lưu thông qua các thông báo này đảm bảo tính toàn vẹn dữ liệu khi kết thúc phiên.

Cấp độPhương thức/Thông báoĐộ tin cậySử dụng
1viewWillDisappearCaoTrạng thái UI, bản nháp
2viewDidDisappearRất caoDữ liệu quan trọng
3willResignActiveTối đaKhi đưa ứng dụng ra nền

Khuyến nghị: sử dụng kết hợp cả ba cấp độ cho dữ liệu người dùng quan trọng. Đối với trạng thái không quan trọng, cấp độ đầu tiên là đủ. Điều quan trọng là không lưu cùng một dữ liệu nhiều lần — sử dụng cờ dirty cho biết dữ liệu đã thay đổi kể từ lần lưu cuối cùng.

Cần đặc biệt chú ý đến chiến lược cho các màn hình CRUD nơi người dùng nhập dữ liệu. Trên các màn hình như vậy, không nên lưu từng thao tác nhấn phím trong viewWillDisappear — điều đó là quá mức. Sử dụng tự động lưu có độ trễ (debounce) thông qua Timer và chỉ sử dụng viewWillDisappear để lưu cưỡng bức cuối cùng nếu có các thay đổi chưa được lưu. Cách tiếp cận này cân bằng giữa hiệu suất và tính toàn vẹn dữ liệu.

Đối với các ứng dụng sử dụng Core Data, một biện pháp bổ sung là gọi saveContext trong viewWillDisappear chỉ khi có các thay đổi thực tế trong ngữ cảnh đối tượng được quản lý. Kiểm tra context.hasChanges trước khi lưu ngăn chặn việc ghi không cần thiết vào bộ nhớ liên tục và kéo dài tuổi thọ pin của thiết bị. Kết hợp kiểm tra này với lưu toàn cục trong applicationDidEnterBackground.

Lỗi thường gặp trong viewWillDisappear

Sử dụng không đúng viewWillDisappear có thể dẫn đến mất dữ liệu, rò rỉ bộ nhớ và hành vi ứng dụng không ổn định. Hãy xem xét các lỗi phổ biến của nhà phát triển iOS.

Lỗi thứ nhất — chỉ lưu dữ liệu trong viewWillDisappear. Như đã thảo luận ở trên, với cử chỉ pop tương tác, phương thức được gọi ngay cả khi màn hình không biến mất. Nếu việc lưu có tác dụng phụ — gửi dữ liệu lên máy chủ, thay đổi trạng thái — điều này có thể dẫn đến kích hoạt sai. Thêm kiểm tra isBeingDismissed hoặc isMovingFromParent.

Lỗi thứ hai — không hủy đăng ký khỏi NotificationCenter. Đây là một trong những rò rỉ bộ nhớ phổ biến nhất trong iOS. Nếu bạn đã đăng ký trong viewWillAppear để nhận UIResponder.keyboardWillShowNotification nhưng không hủy đăng ký trong viewWillDisappear, bao đóng sẽ tiếp tục được gọi. Khi bộ điều khiển bị hủy (deinit), bao đóng sẽ tham chiếu đến một đối tượng đã được phân bổ — ứng dụng sẽ bị treo chắc chắn.

Lỗi thứ ba — thực hiện các thao tác đồng bộ nặng. Lưu một lượng lớn dữ liệu, ghi vào Core Data hoặc hệ thống tập tin trong viewWillDisappear sẽ chặn luồng chính. Nếu thao tác kéo dài hơn hoạt ảnh chuyển tiếp, UIKit tạm dừng luồng và giao diện bị đông cứng. Chuyển các tác vụ lưu nặng sang hàng đợi nền.

Lỗi thứ tư — quên gọi super. Không gọi super.viewWillDisappear có thể làm hỏng UINavigationController và UITabBarController, chúng sử dụng phương thức này cho trạng thái nội bộ của chúng. Luôn gọi super đầu tiên hoặc cuối cùng, theo tài liệu của Apple.

Vấn đề này trở nên trầm trọng hơn trên iOS với tính năng đa nhiệm tích cực và chuyển đổi ứng dụng. Lỗi thứ năm — sử dụng DispatchQueue.main.async sau khi lưu trong viewWillDisappear. Nếu bạn gửi một khối không đồng bộ đến hàng đợi chính sau khi gọi super.viewWillDisappear, không có gì đảm bảo rằng bộ điều khiển vẫn còn tồn tại vào thời điểm khối đó thực thi. Luôn sử dụng tham chiếu yếu [weak self] trong các bao đóng để ngăn việc truy cập bộ nhớ đã được giải phóng và ngăn ứng dụng bị treo.

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

viewWillDisappear khác viewDidDisappear như thế nào?

viewWillDisappear được gọi khi bắt đầu biến mất khi màn hình vẫn hiển thị. viewDidDisappear được gọi sau khi màn hình đã ẩn hoàn toàn và hoạt ảnh đã kết thúc.

Làm gì với cử chỉ pop bị hủy?

Sử dụng viewDidDisappear để xác nhận lưu hoặc kiểm tra các thuộc tính isMovingFromParent và isBeingDismissed trong viewWillDisappear để xác định xem màn hình có thực sự biến mất hay không.

Có cần hủy đăng ký thủ công khỏi NotificationCenter không?

Có, chắc chắn nếu bạn sử dụng khối hoặc bộ chọn với self. ARC không quản lý các đăng ký NotificationCenter. Trong iOS 9+ đối với các khối, hãy sử dụng tham chiếu yếu và hủy đăng ký trong viewWillDisappear.

Làm thế nào để lưu dữ liệu khi force quit qua viewWillDisappear?

Không có cách nào — force quit không gọi các phương thức vòng đời. Để lưu đảm bảo khi kết thúc ứng dụng, hãy sử dụng UIApplication.willTerminateNotification hoặc lưu dữ liệu theo thời gian thực khi dữ liệu thay đổi.

Liệu viewWillDisappear có thể được gọi khi bộ điều khiển không biến mất không?

, khi cử chỉ pop tương tác, UIKit gọi viewWillDisappear ngay sau khi cử chỉ bắt đầu. Nếu người dùng hủy cử chỉ, màn hình vẫn hiển thị nhưng phương thức đã được kích hoạt. Luôn kiểm tra isMovingFromParent.

Tổng kết

  • viewWillDisappear được gọi trước mỗi lần màn hình biến mất — khi push, pop, present và dismiss
  • Mục đích chính là lưu trạng thái, hủy đăng ký thông báo và dừng hoạt ảnh
  • Với các cử chỉ tương tác, phương thức có thể được gọi mà không có sự ẩn thực tế nào của màn hình
  • Sử dụng chiến lược lưu ba cấp độ cho dữ liệu người dùng quan trọng
  • Hủy đăng ký khỏi NotificationCenter trong viewWillDisappear ngăn rò rỉ bộ nhớ
  • Các thao tác đồng bộ nặng chặn luồng chính — chuyển chúng sang hàng đợi nền
  • Luôn gọi super.viewWillDisappear để duy trì điều hướng chính xác

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