ProgramlamaMobil Geliştirici

GCD (Grand Central Dispatch) ve DispatchQueue'un Swift'teki çalışma mantığını açıklayın, asenkron kodu nasıl doğru bir şekilde oluşturursunuz ve çoklu iş parçacığı ile çalışırken hangi tuzaklarla karşılaşabilirsiniz?

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap.

Soru Geçmişi

Grand Central Dispatch (GCD), 2009 yılında iOS ve macOS'ta, kuyruklar - DispatchQueue'ya dayalı olarak, rekabetçi, asenkron kodu organize etmek için düşük seviyeli bir sistem olarak geldi. GCD, görevlerin güvenli bir şekilde yürütülmesini, senkronizasyonu ve kullanımı kolay bir API sağladı ve manuel iş parçacığı yönetiminden çok daha özlüydü.

Sorun

Asenkronluk ve çoklu iş parçacığı, geleneksel olarak çoğu sorunun kaynağıdır: veri yarışları, deadlocklar, arayüzün kapanması ve karmaşık çökmeler. Kuyrukların yanlış kullanımı veya UI'ye ana iş parçacığı dışından erişim girişimleri, hatalara yol açar.

Çözüm

Swift, arka planda çalışma yaratmayı ve arayüzü güncellemek için ana iş parçacığına güvenli bir şekilde geri dönmeyi kolaylaştırır; küresel ve kullanıcı tanımlı kuyruklar ile. Asenkron iş için DispatchQueue'yu kullanın ve bir dizi asenkron görevin tamamlanmasını beklemeniz gerektiğinde DispatchGroup'u kullanın.

Kod örneği:

let backgroundQueue = DispatchQueue(label: "background", qos: .background) backgroundQueue.async { // arka planda çalışıyor let image = downloadImage() DispatchQueue.main.async { // UI'yi güvenli şekilde güncelleme imageView.image = image } }

Anahtar özellikler:

  • DispatchQueue.async, bloğu asenkron olarak yürütür
  • DispatchQueue.main.async, ana iş parçacığında çağrı için
  • DispatchSemaphore, DispatchGroup, sync, ve görev önceliği kontrolü için qos

Tuzaklı Sorular.

Ana kuyruk üzerinde ana iş parçacığından sync çağrılırsa ne olur?

Deadlock meydana gelir: ana iş parçacığı kendisi üzerinde görevlerin yürütülmesini bekler ve uygulama "donar".

DispatchQueue.main.sync { // DEADLOCK }

DispatchQueue.serial, görevleri paralel olarak yürütebilir mi?

Hayır, seri kuyruk her zaman görevleri birer birer yürütür; ancak birkaç seri kuyruk oluşturursanız, bunlar birbirleriyle paralel çalışır.

Ana iş parçacığı dışından arayüzü güncellemeye izin var mı?

Hayır, UIKit (veya SwiftUI View rendering) ile ilgili herhangi bir işlem yalnızca DispatchQueue.main üzerinden yapılabilir. Bu kurala uyulmaması, istikrarsız çalışmalara ve çöküşlere yol açacaktır.

Tipik Hatalar ve Anti-Desenler

  • Ana iş parçacığında senkron çağrı yapılması (deadlock)
  • Arka plandan UI'yı güncelleme girişimi
  • Paylaşılan değişkenlere yazma sırasında kontrolsüz kaynak yarışı
  • Gereksiz global kuyruk kullanımı, ayrılmış kuyrukların olmayışı

Hayattan Bir Örnek

Olumsuz Durum

Arka planda veriler yükleniyor, hemen UI güncelleniyor — uygulama bazen çöküyor veya arayüz donuyor. Ayrıca, senkronizasyon olmadan iş parçacıkları arasında paylaşılan değişken durumları kullanılıyor.

Artıları:

  • Kod görsel olarak özlü

Eksileri:

  • İstikrarsız hatalar ve nadir tekrar eden çökmeler
  • Performans kayıpları

Olumlu Durum

Tüm UI güncellemelerinin yalnızca DispatchQueue.main üzerinde organize edilmesi, büyük verilerle çalışmak için ayrılmış kuyruklar, asenkron görevlerin tamamlanmasını kontrol etmek için DispatchGroup kullanımı.

Artıları:

  • Yarış yok
  • İşlerin iş parçacıkları arasında etkili bir şekilde bölünmesi
  • Kolay bakım

Eksileri:

  • İş parçacıkları arasında çok fazla "dönüş" gerekiyor, paylaşılan kaynaklarla çalışma konusunda disiplin gerekiyor