Kaip sinchronizuoti duomenis tarp srautų ir užtikrinti konteksto nuoseklumą?
sobes.tech AI
Atsakymas iš AI
Duomenų sinchronizavimui ir konteksto nuoseklumo užtikrinimui daugialypėje iOS programoje naudojami šie metodai:
-
NSLock / Lock: Paprasti mutex'ai, skirti užrakinti kritines kodo sekcijas:
import Foundation class ThreadSafeCounter { private var count: Int = 0 private let lock = NSLock() func increment() { lock.lock() defer { lock.unlock() } count += 1 } func getCount() -> Int { lock.lock() defer { lock.unlock() } return count } } -
NSRecursiveLock: Leidžia pakartotinai įgyti užraktą iš to paties srauto:
import Foundation class RecursiveLocker { private let lock = NSRecursiveLock() func firstMethod() { lock.lock() defer { lock.unlock() } print("Pirmoji metodas") secondMethod() // Galima pakartotinai įgyti } func secondMethod() { lock.lock() defer { lock.unlock() } print("Antrasis metodas") } } -
NSCondition / NSConditionLock: Leidžia srautams laukti tam tikro sąlygos (Condition) arba reikšmės (ConditionLock) prieš tęsiant vykdymą. Naudojama gamintojų-vartotojų modelio įgyvendinimui:
import Foundation class Buffer { private var items: [Int] = [] private let condition = NSCondition() private let capacity = 5 func addItem(_ item: Int) { condition.lock() defer { condition.unlock() } while items.count == capacity { condition.wait() // Laukia, kol atsiras laisva vieta } items.append(item) print("Pridėta: \(item), Dabartinis buferis: \(items)") condition.signal() // Signalizuoja laukiančius srautus } func removeItem() -> Int { condition.lock() defer { condition.unlock() } while items.isEmpty { condition.wait() // Laukia, kol atsiras elementas } let item = items.removeFirst() print("Pašalintas: \(item), Dabartinis buferis: \(items)") condition.signal() // Signalizuoja laukiančius srautus return item } } -
**Grand Central Dispatch (GCD):
-
Serial Queues: Atlieka užduotis eilės tvarka, viena po kitos, užtikrinant prieigos atomarumumą prie išteklių.
-
Concurrent Queues su Barrier Flags: Leidžia atlikti skaitymą lygiagrečiai, tačiau rašymo operacijos vykdomos išskirtinai. Tai įgyvendina skaitymo-rašto užrakinimo modelį:
import Foundation class ThreadSafeArray<Element> { private var array: [Element] = [] private let queue = DispatchQueue(label: "com.mycompany.threadsafearray", attributes: .concurrent) // Lygiagretusis eilė func append(_ newElement: Element) { queue.async(flags: .barrier) { // Barjeras rašymui self.array.append(newElement) } } func get(at index: Int) -> Element? { var result: Element? queue.sync { // Sinchronizacija skaitymui if index < self.array.count { result = self.array[index] } } return result } }
-
-
Core Data kontekstų operacijos: Kiekvienas
NSManagedObjectContextturi savo privatų serializuotą srautą. Prieiga prie objektų ir konteksto turi būti vykdoma tik iš šio srauto:import CoreData // Pavyzdys išsaugojimo Core Data kontekste let context = // Gauta kontekstas context.perform { // Vykdymas privačiame konteksto sraute // Darbas su Core Data objektais do { try context.save() } catch { // Klaidos apdorojimas } }
Pasirinkimas priklauso nuo konkrečios užduoties ir našumo reikalavimų. GCD su eilės ar lygiagrečiomis eilėmis su barjerais dažnai yra efektyviausias ir patogiausias būdas. Core Data naudokite tik perform arba performAndWait metodus.