1. Unutulan `await` Kullanımı
Asenkron programlama söz konusu olduğunda, `async` fonksiyonlarını doğru bir şekilde kullanmak kritik öneme sahiptir. Ancak bazen, asenkron bir fonksiyonu çağırırken `await` kelimesini unutmak çok yaygın bir hata olabilir. Bu hatayı yaptığınızda, fonksiyonun çalışması beklenmediği şekilde hızlanır ve beklenen sonucu alamazsınız.
Çözüm:
Asenkron fonksiyonların her çağrısında `await` kelimesini kullanmaya özen gösterin. Bu, fonksiyonun tamamlanmasını beklemenizi sağlar ve kodunuzun sırasıyla çalışmasını garanti eder.
func fetchData() async -> String {
return "Veri Başarıyla Alındı!"
}
Task {
let data = await fetchData()
print(data)
}
2. `DispatchQueue` Kullanımında Dikkatsizlik
Asenkron kod yazarken sıklıkla `DispatchQueue` kullanarak ana iş parçacığını (main thread) engellememeniz gerektiğini unuturuz. Ancak bir işlemi yanlış iş parçacığında çalıştırmak, uygulamanızın donmasına veya yavaşlamasına neden olabilir.
Çözüm:
Asenkron işlemleri doğru iş parçacığında başlatmak için `DispatchQueue.main.async` veya `DispatchQueue.global()` kullanmayı unutmayın. Bu sayede ana iş parçacığını boğmaz ve performansı artırırsınız.
DispatchQueue.global().async {
let data = fetchData()
DispatchQueue.main.async {
print(data)
}
}
3. Döngülerde Asenkron Kodların Yönetimi
Döngülerde asenkron kodları kullanmak, yanlış yapılandırıldığında karmaşık hale gelebilir. Özellikle, asenkron fonksiyonların sonuçlarının sırasıyla alınması gerektiğinde bu durum zorlayıcı olabilir.
Çözüm:
Birden fazla asenkron işlemi sırasıyla yürütmek için `Task` veya `async/await` yapısını doğru şekilde kullanmalısınız. Aşağıda, döngüde asenkron işlemleri sırasıyla nasıl çalıştırabileceğinizi gösteren bir örnek bulabilirsiniz:
func fetchData(for item: Int) async -> String {
return "Veri \(item) Alındı!"
}
func fetchAllData() async {
for i in 0..<5 {
let data = await fetchData(for: i)
print(data)
}
}
Task {
await fetchAllData()
}
4. Hata Yönetimi Eksikliği
Asenkron kod yazarken, hata yönetimi genellikle ihmal edilir. `try` ve `catch` kullanarak hataların düzgün bir şekilde ele alınması gerekir. Hata yönetiminin eksik olduğu durumlarda, kodun beklenmedik şekilde çalışmasına veya çökmelere yol açabilir.
Çözüm:
Asenkron fonksiyonlarda hata yönetimi yapmak için `do-catch` bloklarını kullanmayı unutmayın. Bu, hataları yakalayarak kullanıcı deneyimini iyileştirir.
func fetchData() async throws -> String {
if Bool.random() {
throw NSError(domain: "", code: -1, userInfo: nil)
}
return "Veri Başarıyla Alındı!"
}
Task {
do {
let data = try await fetchData()
print(data)
} catch {
print("Hata oluştu: \(error.localizedDescription)")
}
}
5. Asenkron Kodun Performansını Düşürmek
Asenkron kod yazarken performansı artırmaya yönelik küçük hatalar da yapılabilir. Örneğin, her asenkron işlemi bir `Task` içinde başlatmak yerine gereksiz yere birden fazla işlem başlatmak, sistem kaynaklarını boşa harcayabilir. Bu, özellikle çok sayıda veri çekme işlemi yapılırken daha belirgin hale gelir.
Çözüm:
Birden fazla asenkron işlemi eşzamanlı olarak başlatmak için `async let` kullanarak kodunuzu daha verimli hale getirebilirsiniz. Böylece birden fazla işlemi aynı anda başlatabilir ve sonuçlarını bekleyebilirsiniz.
func fetchData(for item: Int) async -> String {
return "Veri \(item) Alındı!"
}
Task {
async let data1 = fetchData(for: 1)
async let data2 = fetchData(for: 2)
async let data3 = fetchData(for: 3)
let results = await [data1, data2, data3]
for result in results {
print(result)
}
}
Sonuç
Asenkron programlama, Swift geliştiricileri için güçlü bir araçtır. Ancak, yukarıda bahsedilen hataları yapmamak ve doğru teknikleri kullanmak, kodunuzu daha güvenilir ve verimli hale getirir. Hata yönetimi, iş parçacığı yönetimi ve asenkron işlerin doğru sırasıyla çalıştırılması, yazılımınızın hem performansını hem de kullanıcı deneyimini artıracaktır. Bu önerilerle, Swift dilinde asenkron kod yazarken karşılaşacağınız zorlukları kolayca aşabilirsiniz.