Чӣ гуна ҳамоҳангсозии маълумот байни ҷараёнҳо (контекст) дар iOS?
sobes.tech AI
Ҷавоб аз AI
Для синхронізації можна використовувати наступні механізми:
-
NSLock: Примітивний блокуючий мьютекс.
let lock = NSLock() func doSomething() { lock.lock() // Критична секція коду lock.unlock() } -
NSRecursiveLock: Дозволяє одному потоку багаторазово захоплювати блокування без дедлоку.
let recursiveLock = NSRecursiveLock() func recursiveFunction(level: Int) { recursiveLock.lock() if level < 3 { recursiveFunction(level: level + 1) } recursiveLock.unlock() } -
NSCondition: Дозволяє потокам чекати певної умови, перш ніж продовжити виконання.
let condition = NSCondition() var dataAvailable = false func producer() { condition.lock() // Виробництво даних dataAvailable = true condition.signal() // Сигналізувати очікуючим потокам condition.unlock() } func consumer() { condition.lock() while !dataAvailable { condition.wait() // Чекати, поки умова не виконається } // Обробка даних dataAvailable = false condition.unlock() } -
NSConditionLock: Мьютекс, який може бути захоплений тільки при виконанні певної умови-значення.
let conditionLock = NSConditionLock(condition: 0) let DATA_READY = 1 func producer() { conditionLock.lock(when: 0) // Захопити при умові 0 // Виробництво даних conditionLock.unlock(withCondition: DATA_READY) // Зняти блокування і встановити умову DATA_READY } func consumer() { conditionLock.lock(when: DATA_READY) // Захопити при умові DATA_READY // Обробка даних conditionLock.unlock(withCondition: 0) // Зняти блокування і встановити умову 0 } -
Dispatch Queues (GCD): Використання послідовних dispatch-черг для доступу до спільних ресурсів.
let serialQueue = DispatchQueue(label: "com.yourapp.serialQueue") var sharedResource = 0 func updateResource() { serialQueue.async { // Доступ до sharedResource тільки з цієї черги sharedResource += 1 } } -
NSOperationQueue: Дозволяє контролювати залежності та пріоритети операцій.
let operationQueue = OperationQueue() var sharedOperationResource = 0 let operation1 = BlockOperation { // Доступ до sharedOperationResource sharedOperationResource += 1 } operationQueue.addOperation(operation1) -
Actors (Swift 5.5+): Забезпечують ізоляцію стану, запобігаючи одночасному доступу з різних контекстів.
actor Counter { private var count = 0 func increment() { count += 1 } func getCount() -> Int { return count } } let counter = Counter() Task { await counter.increment() let currentCount = await counter.getCount() print(currentCount) } -
Core Data Contexts: Для синхронізації data contexts можна використовувати ієрархічні контексти (батько-потомок) або mergeChanges(fromContextDidSaveNotification:).
// Приклад з ієрархією (батько - фоновий, нащадок - UI) let privateMoc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) privateMoc.persistentStoreCoordinator = persistentStoreCoordinator let mainMoc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) mainMoc.parent = privateMoc // Приклад з mergeChanges NotificationCenter.default.addObserver(self, selector: #selector(contextDidSave(_:)), name: .NSManagedObjectContextDidSave, object: nil) @objc func contextDidSave(_ notification: Notification) { guard let savingContext = notification.object as? NSManagedObjectContext else { return } if savingContext != mainMoc { // Якщо збереження відбулося не в основному контексті mainMoc.perform { mainMoc.mergeChanges(fromContextDidSave: notification) } } } -
Atomic operations: Використання атомарних примітивів (наприклад, з
os/lock.h) для простих операцій.
Вибір методу залежить від складності задачі, типу даних і вимог до продуктивності. Actors і GCD є сучасними та рекомендованими підходами.