Ang NSFileCoordinator ay isang Foundation class sa iOS at macOS na nagbibigay ng ligtas na access sa mga file kapag maraming thread, proseso, o extension ang sabay na gumagana. Ayon sa Apple Developer Documentation, 2024, pinipigilan ng NSFileCoordinator ang race conditions sa pagbabasa at pagsulat ng mga file, na ginagarantiyang walang proseso ang magbabasa ng data habang binabago ito ng iba. Ginagamit ang coordinator sa iCloud Drive, File Provider Extension, at anumang multi-thread na operasyon ng file.
Mga Pangunahing Punto
NSFileCoordinator — ay isang mekanismo ng pag-sync ng access sa file sa antas ng operating system, na ipinakilala ng Apple sa iOS 5 at macOS 10.7 Lion. Hindi tulad ng tradisyonal na pag-lock (NSLock, pthread_mutex), gumagana ang coordinator sa antas ng file system at maaaring mag-coordinate ng access sa pagitan ng iba't ibang proseso, hindi lamang sa pagitan ng mga thread ng isang application.
Ang pangangailangan para sa NSFileCoordinator ay nagmumula sa Sandbox architecture sa iOS: bawat proseso (application, extension, system service) ay gumagana sa isang nakahiwalay na kapaligiran na may sariling access sa mga file. Kapag maraming proseso ang sumusubok na sabay na magbasa at magsulat ng parehong file (halimbawa, sa pag-sync ng iCloud Drive), kung walang coordinator ay lumilitaw ang race conditions: binabasa ng proseso A ang file sa sandaling bahagyang na-overwrite na ito ng proseso B.
Ayon sa WWDC 2023, mariing inirerekomenda ng Apple ang paggamit ng NSFileCoordinator para sa lahat ng operasyon ng file sa Ubiquity container (iCloud Drive) at kapag nagtatrabaho sa File Provider Extension. Ang pagbalewala sa koordinasyon ay isa sa mga karaniwang sanhi ng pagkasira ng data at hindi reproducible na bug sa mga iOS application.
Intensyon ng koordinasyon (NSFileCoordinator.ReadingIntent / WritingIntent) — ay isang bagay na nagdedeklara ng uri ng operasyon na pinaplano ng isang thread o proseso na isagawa. Ginagamit ng coordinator ang mga intensyong ito upang matukoy ang pagkakasunud-sunod ng access at malutas ang mga conflict.
| Uri ng intensyon | Paglalarawan | Kailan gagamitin |
|---|---|---|
| ReadingIntent | Pagbabasa ng file nang walang pagbabago | Pagbubukas ng dokumento, pag-load ng data |
| WritingIntent | Pagsulat na may posibleng pagbabago ng nilalaman | Pag-save ng dokumento, pag-edit |
| ReadingIntent(URL, options: .withoutChanges) | Pagbabasa nang hindi sinusubaybayan ang mga pagbabago | Mabilis na pag-preview ng nilalaman |
| WritingIntent(URL, options: .contentIndependentMetadataOnly) | Pagbabago lamang ng metadata | Pag-update ng petsa o mga attribute |
| WritingIntent(URL, options: .forDeleting) | Pag-delete ng file | Pag-delete ng dokumento ng user |
Mga panuntunan ng koordinasyon: pinapayagan ang maraming sabay na pagbasa (kung walang aktibong pagsulat), ang pagsulat ay eksklusibo — walang pagbasa o pagsulat ang pinapayagan sa panahon ng operasyon ng pagsulat. Ito ay tumutugma sa readers-writer lock model, ngunit may karagdagang suporta para sa inter-process coordination sa pamamagitan ng launchd at XPC.
Mahalagang nuance: Hindi pinipigilan ng NSFileCoordinator ang access sa file sa pamamagitan ng ordinaryong NSData o FileManager — ito ay nag-coordinate lamang ng mga operasyon na explicitly nakabalot sa mga coordination block. Kung ang ibang thread ay direktang pumunta sa file, na lumalampas sa coordinator, lilitaw ang mismong race conditions na dapat pigilan ng coordinator.
Pangunahing pattern ng paggamit ng NSFileCoordinator ay binubuo ng tatlong hakbang: paggawa ng instance ng coordinator, pagdedeklara ng intensyon (pagbasa o pagsulat), at pagsasagawa ng operasyon sa loob ng coordination block. Ginagarantiyahan ng coordinator na walang ibang coordinator ang sabay na gagana sa parehong file.
import Foundation
let coordinator = NSFileCoordinator()
let fileURL = getDocumentURL()
// Ligtas na pagbasa
let readIntent = NSFileCoordinator
.ReadingIntent(url: fileURL)
var content: Data?
var readError: NSError?
coordinator.coordinate(with: readIntent) { error in
if let error = error {
readError = error
return
}
content = try? Data(contentsOf: fileURL)
}
// Ligtas na pagsulat
let writeIntent = NSFileCoordinator
.WritingIntent(url: fileURL)
coordinator.coordinate(with: writeIntent) { error in
guard error == nil else { return }
do {
try newData.write(to: fileURL)
} catch {
Logger.storage.error(
"Write failed: \(error)"
)
}
}
Batch operation — kayang iproseso ng coordinator ang maraming file sa isang operasyon gamit ang array ng mga intensyon. Ito ay maginhawa para sa paglipat, pagkopya, o pag-delete ng isang set ng mga file bilang isang transaksyon. Kung ang isa sa mga intensyon ay hindi maisagawa, ang buong operasyon ay kakanselahin na may error.
let coordinator = NSFileCoordinator()
let readIntent = NSFileCoordinator
.ReadingIntent(url: sourceURL)
let writeIntent = NSFileCoordinator
.WritingIntent(url: destURL)
coordinator.coordinate(
with: [readIntent, writeIntent]
) { error in
try? FileManager.default
.copyItem(at: sourceURL, to: destURL)
}
Asynchronous na koordinasyon — mula noong iOS 15, sinusuportahan ng NSFileCoordinator ang mga asynchronous na pamamaraan na may completion handler, na nagpapahintulot sa pagsasagawa ng koordinasyon nang hindi hinaharangan ang tumatawag na thread. Ito ay kritikal para sa UI thread, kung saan ang synchronous na paghihintay para sa koordinasyon ay maaaring maging sanhi ng pag-freeze ng interface nang ilang segundo.
NSFilePresenter — ay isang protocol na ipinapatupad ng isang bagay para makatanggap ng mga notification tungkol sa mga pagbabago sa file na ini-coordinate ng NSFileCoordinator. Kung ang iyong application ay nagpapakita ng nilalaman ng isang file na maaaring baguhin ng ibang proseso (halimbawa, nag-sync ang iCloud Drive ng bagong bersyon), ang pagpapatupad ng NSFilePresenter ay nagpapahintulot sa napapanahong pag-update ng interface.
class DocumentPresenter: NSFilePresenter {
let presentedItemURL: URL?
let presentedItemOperationQueue: OperationQueue
init(url: URL) {
presentedItemURL = url
presentedItemOperationQueue = OperationQueue()
}
func presentedItemDidChange() {
DispatchQueue.main.async {
NotificationCenter.default
.post(name: .documentDidChange,
object: self)
}
}
func presentedItemDidMove(to newURL: URL) {
Logger.storage.info(
"File moved to: \(newURL.lastPathComponent)"
)
}
func accommodatePresentedItemDeletion(
completionHandler: @escaping (Error?) -> Void
) {
Logger.storage.warn("File deleted externally")
completionHandler(nil)
}
}
Mga pamamaraan ng protocol: ang presentedItemDidChange ay tinatawag kapag nagbago ang nilalaman ng file, presentedItemDidMove(to:) — pagkatapos ilipat ang file, accommodatePresentedItemDeletion — bago i-delete ang file ng ibang proseso (nagbibigay-daan sa application na isara nang tama ang file). Bukod pa rito, sinusuportahan ng protocol ang versioning sa pamamagitan ng presentedItemDidGainVersion: at presentedItemDidLoseVersion:.
Mahalaga: Ang NSFilePresenter ay dapat nakarehistro sa system sa pamamagitan ng NSFileCoordinator.addFilePresenter:. Kung walang rehistrasyon, hindi maihahatid ang mga notification. Ang rehistrasyon ay ginagawa nang isang beses sa pagsisimula ng application at hindi nangangailangan ng muling pagpaparehistro kapag muling ginawa ang presenter.
Palaging gamitin ang coordinator para sa mga file sa Ubiquity container (iCloud Drive) at mga directory na accessible sa mga extension. Kahit na ang application ay kasalukuyang single-thread, ang mga update sa hinaharap o pagbabago sa system ay maaaring magdagdag ng parallel access, at ang kakulangan ng koordinasyon ay hahantong sa mga bug na mahirap mahanap.
I-minimize ang oras sa coordination block. Habang isinasagawa ang block, hindi ma-access ng ibang proseso ang file. Ang mga mahabang operasyon sa loob ng block (komplikadong pagproseso ng data, mga network request) ay humaharang sa buong sistema ng access ng file. Gawin lamang ang pagbasa o pagsulat ng data sa loob ng block, at ang pagproseso sa labas nito.
Iwasan ang deadlock: huwag tawagan ang coordinator mula sa loob ng block ng ibang coordinator para sa parehong file — ito ay hahantong sa mutual blocking. Gumamit ng batch operations (array ng mga intensyon) sa halip na nested na mga tawag. Kung kinakailangan ang nesting, gumamit ng iba't ibang queue o iba't ibang URL.
Ayon sa objc.io (2024), ang mga karaniwang error sa pagtatrabaho sa NSFileCoordinator ay kinabibilangan ng: kawalan ng paghawak ng error sa completion handler (humahantong sa hindi natapos na operasyon); koordinasyon para lamang sa pagsulat, ngunit hindi para sa pagbasa; paggamit ng lumang synchronous API sa UI thread; pagbalewala sa NSFilePresenter protocol kapag nagtatrabaho sa iCloud Drive. Ang huling error ay ang pinaka mapanlinlang: ang application ay nagpapakita ng lumang data nang hindi alam na ang file ay nabago na.
Mga Madalas Itanong
NSFileCoordinator — Foundation class para sa ligtas na access sa mga file mula sa maraming thread o proseso. Pinipigilan ang race conditions sa pamamagitan ng pag-coordinate ng read at write operations sa antas ng file system.
NSLock ay gumagana lamang sa loob ng isang proseso (sa pagitan ng mga thread). Ang NSFileCoordinator ay nag-coordinate ng access sa pagitan ng iba't ibang proseso at extension, kabilang ang iCloud Drive sync at File Provider Extension.
Oo, mariing inirerekomenda ng Apple ang paggamit ng NSFileCoordinator para sa lahat ng operasyon ng file sa Ubiquity container. Kung walang coordinator, posible ang pagkasira ng data sa panahon ng pag-sync sa pagitan ng mga device at mga conflict sa File Provider Extension.
NSFilePresenter — protocol para sa pagtanggap ng mga notification ng pagbabago ng file. Nagbibigay-daan sa application na tumugon sa mga pagbabagong ginawa ng ibang proseso: pag-update ng UI sa pagbabago, paghawak ng paglipat, o paghahanda para sa pag-delete ng file.
Limang uri: ReadingIntent (pagbasa), WritingIntent (pagsulat), ReadingIntent na may .withoutChanges (pagbasa nang walang pagsubaybay), WritingIntent na may .contentIndependentMetadataOnly (metadata lamang) at WritingIntent na may .forDeleting (pag-delete). Bawat isa ay tumutukoy sa antas ng access sa file.
Buod
Gagawa kami ng mobile application na turnkey
Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.
Basahin din