Kuidas sünkroonida andmeid vahel niitide (konteksti) iOS-is?
sobes.tech AI
Vastus AI-lt
Sünkroniseerimiseks saab kasutada järgmisi mehhanisme:
-
NSLock: Põhiline lukustus-mutex.
let lock = NSLock() func doSomething() { lock.lock() // Kriitiline koodiosa lock.unlock() } -
NSRecursiveLock: Annab ühele niidile võimaluse mitu korda lukustada ilma deadlockita.
let recursiveLock = NSRecursiveLock() func recursiveFunction(level: Int) { recursiveLock.lock() if level < 3 { recursiveFunction(level: level + 1) } recursiveLock.unlock() } -
NSCondition: Annab niitidele võimaluse oodata teatud tingimust enne jätkamist.
let condition = NSCondition() var dataAvailable = false func producer() { condition.lock() // Andmete tootmine dataAvailable = true condition.signal() // Signaali saatmine ootavatele niitidele condition.unlock() } func consumer() { condition.lock() while !dataAvailable { condition.wait() // Oodata, kuni tingimus on täidetud } // Andmete töötlemine dataAvailable = false condition.unlock() } -
NSConditionLock: Mutex, mida saab haarata ainult teatud tingimuse väärtuse korral.
let conditionLock = NSConditionLock(condition: 0) let DATA_READY = 1 func producer() { conditionLock.lock(when: 0) // Haarata, kui tingimus on 0 // Andmete tootmine conditionLock.unlock(withCondition: DATA_READY) // Vabastada ja seada tingimuseks DATA_READY } func consumer() { conditionLock.lock(when: DATA_READY) // Haarata, kui tingimus on DATA_READY // Andmete töötlemine conditionLock.unlock(withCondition: 0) // Vabastada ja seada tingimuseks 0 } -
Dispatch Queues (GCD): Kasutades järjestusjärjekordi, et pääseda ligi ühistele ressurssidele.
let serialQueue = DispatchQueue(label: "com.yourapp.serialQueue") var sharedResource = 0 func updateResource() { serialQueue.async { // Pääs ainult selle järjekorra kaudu sharedResource += 1 } } -
NSOperationQueue: Annab võimaluse kontrollida sõltuvusi ja prioriteete operatsioonidele.
let operationQueue = OperationQueue() var sharedOperationResource = 0 let operation1 = BlockOperation { // Pääs sharedOperationResource'ile sharedOperationResource += 1 } operationQueue.addOperation(operation1) -
Actors (Swift 5.5+): Tagab oleku isolatsiooni, vältides samaaegset juurdepääsu erinevatest kontekstidest.
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: Andmekontekstide sünkroniseerimiseks saab kasutada hierarhilisi kontekste (vanem-laps) või mergeChanges(fromContextDidSaveNotification:).
// Näide hierarhiaga (vanem - taust, laps - UI) let privateMoc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType) privateMoc.persistentStoreCoordinator = persistentStoreCoordinator let mainMoc = NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType) mainMoc.parent = privateMoc // Näide mergeChanges'ist 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 { // Kui salvestus toimus mitte põhikontekstis mainMoc.perform { mainMoc.mergeChanges(fromContextDidSave: notification) } } } -
Atomioperatsioonid: Kasutades atomaarseid primitiive (nt
os/lock.h) lihtsate operatsioonide jaoks.
Valitud meetod sõltub ülesande keerukusest, andmetüübist ja nõutavast jõudlusest. Actors ja GCD on kaasaegsed ja soovitatavad lähenemised.