Qanday qilib oqimlar orasida ma'lumotlarni sinxronlashtirish va kontekstning muvofiqligini ta'minlash mumkin?
sobes.tech AI
AIdan javob
iOS-да кўп иш парчаларида маълумотларни синхронлаштириш ва контекстнинг мувофиқлигини таъминлаш учун қуйидаги ёндашувлар қўлланилади:
-
NSLock / Lock: Мутекслар критик қисмларни блоклаш учун оддий.
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: Ўзингиздан кейинги блокировкани қайта олишга imkon беради.
import Foundation class RecursiveLocker { private let lock = NSRecursiveLock() func firstMethod() { lock.lock() defer { lock.unlock() } print("Биринчий метод") secondMethod() // Такрор олиш мумкин } func secondMethod() { lock.lock() defer { lock.unlock() } print("Иккинчи метод") } } -
NSCondition / NSConditionLock: Ўзгарувчи шарт ёки қийматга кутилган ҳолда, уларни бажариш учун кутилган. Бу producer-consumer моделини амалга ошириш учун қўлланилади.
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() // бўш жой пайдо бўлгунча кутинг } items.append(item) print("Қўшилди: \(item), Ҳозирги буфер: \(items)") condition.signal() // кутилган иш парчаларга сигнал беринг } func removeItem() -> Int { condition.lock() defer { condition.unlock() } while items.isEmpty { condition.wait() // элемент пайдо бўлгунча кутинг } let item = items.removeFirst() print("Ўчирилди: \(item), Ҳозирги буфер: \(items)") condition.signal() // бўш жойга кутилган иш парчаларга сигнал беринг return item } } -
Grand Central Dispatch (GCD):
-
Serial Queues: Вазифаларни навбат билан, бир вақтда бирини бажаради, бу ресурсларга атомар киришни таъминлайди.
-
Concurrent Queues с Barrier Flags: Ўқишни параллель бажаришга imkon беради, аммо ёзиш операциялари (write) эксклюзив бажарилади. Бу read-write lock моделини амалга оширади.
import Foundation class ThreadSafeArray<Element> { private var array: [Element] = [] private let queue = DispatchQueue(label: "com.mycompany.threadsafearray", attributes: .concurrent) // Concurrent queue func append(_ newElement: Element) { queue.async(flags: .barrier) { // Barrier ёзув учун self.array.append(newElement) } } func get(at index: Int) -> Element? { var result: Element? queue.sync { // Sync ўқиш учун (ёки async, агар тартиб муҳим бўлмаса) if index < self.array.count { result = self.array[index] } } return result } }
-
-
Core Data Context операциялари: Ҳар бир
NSManagedObjectContextўзининг шахсий сериализланган иш парчасига эга. Объектларга ва контекстга кириш фақат ушбу иш парчасидан амалга оширилиши керак.import CoreData // Core Data контекстида сақлаш мисоли let context = // Олинган контекст context.perform { // Контекстнинг шахсий иш парчасида бажариш // Бу ерда Core Data объектлари билан ишлаш do { try context.save() } catch { // Хатоларни қайта ишлаш } }
Тўғри методни танлаш махсус вазифага ва ишлаш тезлиги талабларига боғлиқ. GCD билан сериализланган ёки concurrent қаторлар ва барьерлар билан ишлаш кўпроқ самарали ва қулай бўлади. Core Data учун, ҳеч қачон perform ёки performAndWait методларидан фойдаланинг.