Sobes.tech
Middle+

İş parçaları arasında verileri nasıl senkronize edilir ve bağlam tutarlılığı nasıl sağlanır?

sobes.tech yapay zeka

AI'dan gelen yanıt

iOS'ta çok iş parçacıklı uygulamalarda veri senkronizasyonu ve bağlam tutarlılığını sağlamak için aşağıdaki yaklaşımlar kullanılır:

  1. NSLock / Lock: Kritik kod bölümlerini kilitlemek için basit mutexler.

    import Foundation
    
    class ThreadSafeCounter {
        private var count: Int = 0
        private let lock = NSLock()
    
        func increment() {
            lock.lock()
            defer { lock.unlock() } // Kilidin garantili serbest bırakılması
            count += 1
        }
    
        func getCount() -> Int {
            lock.lock()
            defer { lock.unlock() }
            return count
        }
    }
    
  2. NSRecursiveLock: Aynı iş parçacığından tekrar kilit alınmasına izin verir.

    import Foundation
    
    class RecursiveLocker {
        private let lock = NSRecursiveLock()
    
        func firstMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("İlk metod")
            secondMethod() // Tekrar kilit alınabilir
        }
    
        func secondMethod() {
            lock.lock()
            defer { lock.unlock() }
            print("İkinci metod")
        }
    }
    
  3. NSCondition / NSConditionLock: İş parçacıklarının belirli bir koşul veya değeri beklemesine izin verir. Üretici-tüketici desenini uygulamak için kullanılır.

    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() // Boş alan oluşmasını bekler
            }
    
            items.append(item)
            print("Eklendi: \(item), Güncel Buffer: \(items)")
            condition.signal() // Bekleyen iş parçacıklarına sinyal gönder
        }
    
        func removeItem() -> Int {
            condition.lock()
            defer { condition.unlock() }
    
            while items.isEmpty {
                condition.wait() // Bir öğe oluşmasını bekler
            }
    
            let item = items.removeFirst()
            print("Kaldırıldı: \(item), Güncel Buffer: \(items)")
            condition.signal() // Boş alan bekleyen iş parçacıklarına sinyal
            return item
        }
    }
    
  4. Grand Central Dispatch (GCD):

    • Sıralı Kuyruklar: Görevleri sıralı olarak, aynı anda bir tane, bu sayede kaynaklara erişimde atomiklik sağlar.

    • Barrier Bayraklı Eşzamanlı Kuyruklar: Okuma işlemlerini eşzamanlı yapmaya izin verir, ancak yazma işlemleri (write) münhasıran yapılır. Bu, okuma-yazma kilidi modelini uygular.

      import Foundation
      
      class ThreadSafeArray<Element> {
          private var array: [Element] = []
          private let queue =
          DispatchQueue(label: "com.mycompany.threadsafearray", attributes: .concurrent) // Eşzamanlı kuyruk
      
          func append(_ newElement: Element) {
              queue.async(flags: .barrier) { // Barrier yazma için
                  self.array.append(newElement)
              }
          }
      
          func get(at index: Int) -> Element? {
              var result: Element?
              queue.sync { // Okuma için senkronizasyon (veya sıralama önemli değilse async)
                  if index < self.array.count {
                      result = self.array[index]
                  }
              }
              return result
          }
      }
      
  5. Core Data Bağlamı İşlemleri: Her NSManagedObjectContext kendi özel seri iş parçacığına sahiptir. Nesnelere ve bağlama erişim yalnızca bu iş parçacığından yapılmalıdır.

    import CoreData
    
    // Core Data bağlamında kaydetme örneği
    let context = // Elde edilen bağlam
    context.perform { // Bağlamın özel iş parçacığında çalıştırma
        // Core Data nesneleriyle burada çalışın
        do {
            try context.save()
        } catch {
            // Hata işleme
        }
    }
    

Yöntem seçimi, belirli göreve ve performans gereksinimlerine bağlıdır. GCD ile sıralı kuyruklar veya barrier bayraklı eşzamanlı kuyruklar genellikle verimlilik ve kullanım kolaylığı nedeniyle tercih edilir. Core Data için, her zaman perform veya performAndWait metodlarını kullanın.