NSFilePresenter: nó là gì, giao thức NSFileCoordinator và phương pháp theo dõi

Tác giả: IT Sectr Đã đăng: 2026-07-12 Thời gian đọc: 7 phút

NSFilePresenter là một giao thức Foundation cho phép một đối tượng nhận thông báo về những thay đổi của tập tin và thư mục trong hệ thống tập tin iOS và macOS. Lớp này triển khai các phương thức của giao thức và đăng ký thông qua NSFileCoordinator, sau đó hệ thống tự động gọi các phương thức này trong bất kỳ thao tác nào với tập tin đang theo dõi. Theo tài liệu dành cho nhà phát triển Apple (2025), NSFilePresenter được sử dụng trong các ứng dụng có truy cập tài liệu đa luồng để ngăn ngừa xung đột ghi. Giao thức phải được sử dụng kết hợp với NSFileCoordinator — chỉ như vậy mới đảm bảo phối hợp truy cập an toàn.

Các điểm chính

  • NSFilePresenter — một giao thức Foundation để theo dõi thay đổi tập tin và thư mục trong iOS và macOS.
  • NSFileCoordinator — một lớp bổ trợ bắt buộc quản lý truy cập và gọi các phương thức ủy quyền.
  • accommodatePresentedItemDeletion — phương thức xử lý việc xóa tập tin đang theo dõi với khả năng hủy bỏ.
  • presentedItemDidChange — được gọi khi nội dung của tập tin hoặc thư mục thay đổi.
  • presentedItemURL — thuộc tính bắt buộc trả về URL của tập tin đang theo dõi.

NSFilePresenter là gì?

NSFilePresenter là một giao thức Foundation được thiết kế để theo dõi thay đổi tập tin và thư mục trong các hệ điều hành Apple. Giao thức xác định một tập hợp các phương thức mà đối tượng quan sát triển khai để nhận thông báo sự kiện hệ thống tập tin.

Mục đích chính của giao thức là cung cấp truy cập tập tin an toàn trong các kịch bản đa luồng. Trong iOS và macOS, nhiều tiến trình và luồng có thể truy cập đồng thời cùng một tập tin thông qua NSFileCoordinator, và NSFilePresenter đảm bảo mỗi người tham gia nhận được trạng thái dữ liệu mới nhất.

Giao thức đã được bao gồm trong Foundation từ iOS 5.0 và macOS 10.7. Nó được sử dụng trong các ứng dụng làm việc với tài liệu, cơ sở dữ liệu và bất kỳ tập tin nào có thể được sửa đổi đồng thời từ nhiều nguồn khác nhau — ví dụ, trong quá trình đồng bộ iCloud hoặc chỉnh sửa cộng tác.

NSFilePresenter được sử dụng ở đâu

Ứng dụng dựa trên tài liệu — lĩnh vực chính sử dụng NSFilePresenter. Các ứng dụng làm việc với UIDocument hoặc NSDocument tự động đăng ký chúng như người trình bày thông qua NSFileCoordinator. Điều này cho phép xử lý chính xác các xung đột khi chỉnh sửa cùng một tập tin từ nhiều cửa sổ hoặc thiết bị.

Đồng bộ iCloud — kịch bản chính thứ hai. Khi một tập tin được sửa đổi trên một thiết bị, iCloud đồng bộ hóa nó trên tất cả các thiết bị đã kết nối. NSFilePresenter thông báo cho ứng dụng về những thay đổi này, cho phép cập nhật giao diện kịp thời.

Trình chỉnh sửa đa luồng — kịch bản thứ ba. Trong các ứng dụng nơi hàng đợi nền tải và lưu dữ liệu đồng thời với công việc của người dùng, NSFilePresenter ngăn ngừa các điều kiện cạnh tranh trong quá trình ghi và đọc tập tin.

NSFilePresenter hoạt động như thế nào?

Cơ chế hoạt động của NSFilePresenter dựa trên mô hình ủy quyền: đối tượng triển khai các phương thức giao thức, đăng ký thông qua NSFileCoordinator và nhận các cuộc gọi mỗi khi tập tin đang theo dõi thay đổi. Hệ thống tự xác định khi nào thay đổi xảy ra và phương thức nào cần gọi.

Quá trình bắt đầu khi đối tượng tạo một thể hiện của NSFileCoordinator và gọi phương thức của bộ điều phối, truyền URL tập tin. Bộ điều phối kiểm tra xem có người trình bày nào được đăng ký cho URL này không. Nếu có, nó chặn quyền truy cập đọc hoặc ghi và thông báo cho người trình bày về thay đổi sắp tới thông qua các phương thức giao thức.

Sau khi hoàn tất thao tác, bộ điều phối giải phóng khóa và gọi các thông báo cuối cùng. Điều quan trọng là người trình bày không điều khiển luồng thực thi — nó chỉ phản ứng với các sự kiện. NSFileCoordinator hoàn toàn chịu trách nhiệm phối hợp.

Vòng đời thông báo

Giai đoạn chuẩn bị — trước khi thực hiện một thao tác, bộ điều phối gọi accommodatePresentedItemDeletion hoặc accommodatePresentedSubitemDeletion. Người trình bày có thể xử lý tình huống hoặc hủy bỏ thao tác bằng cách trả về lỗi. Giai đoạn này cho phép ứng dụng kết thúc công việc với tập tin một cách chính xác trước khi nó bị sửa đổi.

Giai đoạn thông báo — sau khi hoàn tất thao tác, bộ điều phối gọi presentedItemDidChange hoặc presentedSubitemDidChange. Người trình bày nhận được tín hiệu rằng tập tin đã thay đổi và có thể đọc lại nội dung của nó. Đối với việc di chuyển tập tin, presentedItemDidMoveToURL được gọi với vị trí mới.

Giai đoạn kết thúc — bộ điều phối giải phóng tất cả các khóa và tài nguyên. Người trình bày có thể tiếp tục làm việc với dữ liệu đã cập nhật. Cả ba giai đoạn được thực thi đồng bộ trong một luồng duy nhất, vì vậy các phương thức giao thức phải thực thi nhanh mà không có thao tác I/O kéo dài.

Các phương pháp chính của giao thức

Giao thức NSFilePresenter chứa một số phương pháp bắt buộc và tùy chọn. Thuộc tính bắt buộc duy nhất là presentedItemURL, trả về URL của tập tin hoặc thư mục đang theo dõi. Không có thuộc tính này, đối tượng không thể được đăng ký như người trình bày.

Phương pháp bắt buộc

presentedItemURL — một thuộc tính loại URL? phải trả về đường dẫn đến tập tin đang theo dõi. Nếu đối tượng theo dõi nhiều tập tin, thuộc tính trả về URL của mục chính. Đối với thư mục, nó trả về URL của thư mục.

presentedItemDidChange — được gọi sau khi nội dung của tập tin đang theo dõi thay đổi. Trong phương thức này, người trình bày cập nhật trạng thái nội bộ và tải lại dữ liệu. Phương thức này không nhận thông tin về chính xác những gì đã thay đổi — chỉ sự kiện thay đổi.

Phương pháp tùy chọn

accommodatePresentedItemDeletion — được gọi trước khi xóa tập tin. Người trình bày có thể lưu trạng thái hiện tại, đóng bộ mô tả tập tin hoặc hủy bỏ thao tác bằng cách trả về NSError. Nếu phương thức trả về lỗi, thao tác xóa sẽ không được thực hiện.

presentedItemDidMoveToURL — được gọi sau khi di chuyển hoặc đổi tên tập tin. Phương thức nhận URL mới và người trình bày phải cập nhật tham chiếu tập tin. Nếu không triển khai phương thức này, người trình bày sẽ tiếp tục trỏ đến đường dẫn cũ không tồn tại.

NSFilePresenter và NSFileCoordinator

NSFileCoordinatorNSFilePresenter là một cặp không thể tách rời. NSFileCoordinator quản lý truy cập tập tin và gọi các phương thức của người trình bày. Người trình bày không làm việc trực tiếp với hệ thống tập tin — tất cả các thao tác đều thông qua bộ điều phối, đảm bảo tính nguyên tử của các thay đổi.

Bộ điều phối đăng ký người trình bày thông qua phương thức addFilePresenter của lớp NSFileCoordinator. Sau khi đăng ký, người trình bày bắt đầu nhận thông báo. Việc loại bỏ được thực hiện thông qua removeFilePresenter. Hệ thống giữ một tham chiếu yếu đến người trình bày, vì vậy đối tượng phải tồn tại trong suốt thời gian theo dõi.

Theo Apple WWDC 2022, NSFileCoordinator sử dụng cơ chế phối hợp ở cấp hạt nhân, đảm bảo độ trễ tối thiểu trong quá trình khóa. Trong các phiên bản iOS mới nhất, bộ điều phối được tối ưu để làm việc với Sandbox và phần mở rộng ứng dụng.

Quy tắc phối hợp

Intention — mỗi thao tác đọc hoặc ghi phải được bọc trong một khối phối hợp: đọc qua coordinateReadingItemAtURL, ghi qua coordinateWritingItemAtURL. Bộ điều phối tự động khóa tập tin cho những người tham gia khác trong suốt quá trình thực thi khối.

Phối hợp hàng loạt — đối với các thao tác liên quan đến nhiều tập tin, phối hợp hàng loạt được sử dụng. Bộ điều phối khóa nguyên tử tất cả các tập tin được chỉ định, thực hiện thao tác và giải phóng các khóa. Điều này đặc biệt quan trọng khi di chuyển hoặc sao chép các bộ tài liệu.

Ví dụ triển khai

Hãy tạo một lớp DocumentPresenter triển khai giao thức NSFilePresenter và theo dõi các thay đổi của tập tin tài liệu. Lớp này chứa một tham chiếu đến tập tin, dữ liệu nội bộ và một cờ hiệu lực.

swift
import Foundation

class DocumentPresenter: NSObject, NSFilePresenter {
    var presentedItemURL: URL? {
        return self.fileURL
    }

    var presentedItemOperationQueue: OperationQueue {
        return self.queue
    }

    private let fileURL: URL
    private let queue = OperationQueue()

    func presentedItemDidChange() {
        self.reloadData()
    }

    func accommodatePresentedItemDeletion() throws {
        try self.saveCurrentState()
    }

    private func reloadData() {
        let coordinator = NSFileCoordinator(filePresenter: self)
        var error: NSError?
        coordinator.coordinate(readingItemAt: self.fileURL,
                               options: [],
                               error: &error)
        { readURL in
            guard let data = try? Data(contentsOf: readURL)
            else { return }
            self.processData(data)
        }
    }

    private func processData(_: Data) {
        // Xử lý dữ liệu tài liệu
    }
}

Lớp triển khai presentedItemDidChange để tải lại dữ liệu khi tập tin thay đổi và accommodatePresentedItemDeletion để lưu trạng thái trước khi xóa. Hàng đợi thao tác đảm bảo tất cả các thông báo được xử lý tuần tự.

Việc đăng ký người trình bày được thực hiện thông qua NSFileCoordinator.addFilePresenter khi mở một tài liệu. Điều quan trọng là phải truyền các tùy chọn đọc chính xác cho bộ điều phối — withoutChanges cho các thao tác không sửa đổi hoặc immediatelyAvailable cho các kịch bản yêu cầu truy cập ngay lập tức.

Các lỗi thường gặp

Lỗi thường gặp đầu tiên là thiếu triển khai presentedItemOperationQueue. Nếu bạn không chỉ định hàng đợi, các thông báo có thể đến trên một luồng tùy ý, gây ra các điều kiện cạnh tranh dữ liệu. Luôn sử dụng OperationQueue tuần tự để xử lý các thông báo.

Lỗi thứ hai là chặn trong các phương thức của người trình bày. Các phương thức giao thức được gọi đồng bộ từ bộ điều phối. Nếu người trình bày thực hiện một thao tác kéo dài (ghi cơ sở dữ liệu, yêu cầu mạng), nó sẽ chặn bộ điều phối cho tất cả những người tham gia khác. Di chuyển các thao tác nặng sang hàng đợi nền.

Lỗi thứ ba là bỏ qua accommodatePresentedItemDeletion. Nếu người trình bày không triển khai phương thức này và không trả về lỗi, tập tin có thể bị xóa mà không lưu trạng thái hiện tại. Luôn lưu dữ liệu trong phương thức này nếu chưa được ghi vào đĩa.

Lỗi thứ tư là phối hợp vòng. Khi người trình bày bên trong một phương thức thông báo gọi lại bộ điều phối cho cùng một tập tin, deadlock xảy ra. Kiểm tra cờ isCoordinatedOperation trước khi bắt đầu phối hợp trong một bộ xử lý.

LỗiHậu quảGiải pháp
Không có hàng đợi thao tácCạnh tranh dữ liệu trong đa luồngChỉ định OperationQueue
Chặn trong phương thứcBộ điều phối bị treoChuyển sang luồng nền
Bỏ qua xóaMất dữ liệu khi xóaTriển khai lưu
Phối hợp vòngDeadlock ứng dụngCờ isCoordinatedOperation

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

Tại sao cần NSFilePresenter khi đã có NSFileHandle?

NSFileHandle là giao diện cấp thấp để đọc và ghi dữ liệu, không cung cấp cơ chế thông báo về thay đổi từ các tiến trình khác. NSFilePresenter hoạt động ở cấp phối hợp: nó nhận các sự kiện từ hệ thống bất cứ khi nào tập tin thay đổi, bất kể nguồn — một luồng, tiến trình khác hoặc iCloud.

Có bắt buộc phải sử dụng NSFileCoordinator với NSFilePresenter không?

. NSFilePresenter không có ý nghĩa nếu không có NSFileCoordinator. Người trình bày chỉ định nghĩa các phương thức xử lý, trong khi bộ điều phối quản lý các khóa và gọi các phương thức này. Nếu bạn sử dụng NSFilePresenter mà không có bộ điều phối, các thông báo sẽ không được gửi.

Một đối tượng có thể là người trình bày cho nhiều tập tin không?

Có thể, nhưng có giới hạn. Thuộc tính presentedItemURL chỉ trả về một URL, vì vậy để theo dõi nhiều tập tin, giao thức NSFilePresenter được sử dụng với các phương thức bổ sung cho các mục con. Một giải pháp thay thế là tạo một thể hiện người trình bày riêng cho mỗi tập tin.

NSFilePresenter làm việc với Sandbox trong iOS như thế nào?

NSFilePresenter hoàn toàn tương thích với sandbox iOS. Ứng dụng chỉ có thể theo dõi các tập tin trong vùng chứa riêng của nó. Để truy cập tập tin của các ứng dụng khác, App Groups hoặc Security-Scoped Bookmarks được sử dụng. Bộ điều phối hoạt động trong phạm vi quyền của sandbox.

Làm gì nếu presentedItemDidChange được gọi quá thường xuyên?

Sử dụng debounce hoặc throttle bên trong phương thức presentedItemDidChange. Tạo một bộ đếm thời gian với độ trễ 0,3–0,5 giây và đặt lại nó ở mỗi cuộc gọi mới. Sau khi ổn định, thực hiện tải lại dữ liệu. Điều này ngăn ngừa việc xử lý nhiều lần cùng một lô thay đổi.

Tóm tắt

  • NSFilePresenter — một giao thức Foundation để nhận thông báo thay đổi tập tin trong iOS và macOS, hoạt động độc quyền kết hợp với NSFileCoordinator.
  • Thuộc tính bắt buộc presentedItemURL — không có nó, đối tượng không thể được đăng ký như người trình bày và sẽ không nhận được thông báo.
  • Phương thức chính presentedItemDidChange được gọi sau bất kỳ thay đổi nội dung tập tin nào — sử dụng nó để tải lại dữ liệu.
  • accommodatePresentedItemDeletion cho phép xử lý chính xác việc xóa tập tin và lưu trạng thái ứng dụng hiện tại.
  • NSFileCoordinator quản lý các khóa và đảm bảo tính nguyên tử của các thao tác — không có bộ điều phối, người trình bày vô dụng.
  • Các lỗi thường gặp bao gồm thiếu hàng đợi thao tác, chặn trong phương thức và phối hợp vòng — cần tránh bằng cách thiết kế phù hợp.
  • Debounce presentedItemDidChange khi được gọi thường xuyên — sử dụng bộ đếm thời gian để gộp các thay đổi trước khi tải lạ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