Sobes.tech
Middle+

Kā sinhronizēt datus starp pavedieniem un nodrošināt konteksta saskaņotību?

sobes.tech AI

Atbilde no AI

Datu sinhronizācijai un konteksta saskaņošanai daudzšūnu iOS lietojumprogrammā tiek izmantoti šādi pieejas:

  1. NSLock / Lock: Vienkārši mutexi kritisko koda sekciju bloķēšanai:

    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
        }
    }
    
  2. NSRecursiveLock: Atļauj atkārtoti iegūt slēdzeni no tā paša pavediena:

    import Foundation
    
    class RecursiveLocker {
        private let lock = NSRecursiveLock()
    
        func firstMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("Pirmā metode")
            secondMethod() // Iespējams atkārtoti iegūt
        }
    
        func secondMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("Otrā metode")
        }
    }
    
  3. NSCondition / NSConditionLock: Atļauj pavedieniem gaidīt noteiktu nosacījumu vai vērtību pirms turpināt izpildi:

    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() // Gaida, kamēr būs brīva vieta
            }
    
            items.append(item)
            print("Pievienots: \(item), Pašreizējais buferis: \(items)")
            condition.signal() // Signāla gaidošos pavedienus
        }
    
        func removeItem() -> Int {
            condition.lock()
            defer { condition.unlock() }
    
            while items.isEmpty {
                condition.wait() // Gaida, kamēr būs elements
            }
    
            let item = items.removeFirst()
            print("Noņemts: \(item), Pašreizējais buferis: \(items)")
            condition.signal() // Signāla gaidošos pavedienus
            return item
        }
    }
    
  4. **Grand Central Dispatch (GCD):

    • Serial Queues: Veic uzdevumus secīgi, pa vienam, nodrošinot piekļuves atomaritāti resursiem.

    • Concurrent Queues ar Barrier Flags: Atļauj lasīt paralēli, bet rakstīšanas operācijas tiek veiktas ekskluzīvi:

      import Foundation
      
      class ThreadSafeArray<Element> {
          private var array: [Element] = []
          private let queue = DispatchQueue(label: "com.mycompany.threadsafearray", attributes: .concurrent) // Paralēla rinda
      
          func append(_ newElement: Element) {
              queue.async(flags: .barrier) { // Barjers rakstīšanai
                  self.array.append(newElement)
              }
          }
      
          func get(at index: Int) -> Element? {
              var result: Element?
              queue.sync { // Sinhronizācija lasīšanai
                  if index < self.array.count {
                      result = self.array[index]
                  }
              }
              return result
          }
      }
      
  5. Core Data konteksta operācijas: Katrs NSManagedObjectContext ir ar savu privātu sērijveida pavedienu:

    import CoreData
    
    // Piemērs saglabāšanai Core Data kontekstā
    let context = // Saņemtais konteksts
    context.perform { // Darbība privātajā konteksta pavedienā
        // Darbs ar Core Data objektiem
        do {
            try context.save()
        } catch {
            // Kļūdas apstrāde
        }
    }
    

Izvēle ir atkarīga no konkrētās uzdevuma un veiktspējas prasībām. GCD ar rindām vai paralēlām rindām ar barjerām bieži ir visefektīvākais un ērtākais risinājums. Core Data izmanto tikai perform vai performAndWait metodes.