Escaping Closure Nedir?
Bir closure’ın "escaping" olması demek, onun bulunduğu fonksiyondan dışarı çıkıp, fonksiyon çağrıldıktan sonra dahi hafızada kalmaya devam etmesi anlamına gelir. Peki, bu ne demek? Diyelim ki bir asenkron işlem yapıyorsunuz ve işlem tamamlandığında bir closure çalıştırılacak. Bu durumda closure fonksiyonun dışında bir yerde kullanılacak ve fonksiyonun döndürülmesinin ardından kapanış işlemi yapılacaktır. Bu durumda closure "escaping" olur.
Örnek:
Bir URL'den veri çekmek için asenkron bir işlem yapalım.
func fetchData(completion: @escaping (Data?) -> Void) {
DispatchQueue.global().async {
let data = Data() // Burada gerçek veriyi çekiyoruz.
DispatchQueue.main.async {
completion(data)
}
}
}
Bu örnekte, `completion` closure'ı asenkron bir işlem sonrasında çağrılacaktır. Çünkü veri çekme işlemi tamamlandıktan sonra closure’ı çalıştıracağız. İşte bu, closure’ın "escaping" olduğunun bir örneğidir.
Non-Escaping Closure Nedir?
Non-escaping closure’lar, yalnızca fonksiyon bitene kadar geçerli olan closure’lar olup, fonksiyon çağrılmadan önce tamamlanmak zorundadır. Yani, fonksiyon bittikten sonra closure’a erişim mümkün olmaz. Genelde senkron işlemlerde ve küçük, hızlı fonksiyonlar için kullanılır.
Örnek:
Bir başka örneğe bakalım:
func processData(data: [String], process: (String) -> Void) {
for item in data {
process(item)
}
}
Bu fonksiyon, her bir veriyi işlemeyi vaat eder. Buradaki `process` closure'ı bir non-escaping closure’dır çünkü fonksiyon bitene kadar işlem tamamlanacaktır ve başka bir yerde kullanılmaz.
Escaping ve Non-Escaping Arasındaki Farklar
Görünüşte küçük bir fark gibi görünen bu iki closure türü, performans ve bellek yönetimi açısından büyük farklar yaratabilir. İşte bu farklar:
1. Bellek Yönetimi:
* Escaping closure’lar, bellek yönetimi açısından daha karmaşıktır çünkü dışarıya sızan bir closure, nesneleri hafızada tutar ve bu da güçlü referans döngülerine yol açabilir. Eğer bu referans döngülerine dikkat edilmezse, hafıza sızıntıları ortaya çıkabilir.
* Non-escaping closure’lar ise daha hafif yapılar olup, fonksiyon çağrısı sona erdikten sonra bellekten serbest bırakılırlar. Bu, bellek yönetimi açısından daha güvenli bir yaklaşımdır.
2. Performans:
* Non-escaping closure’lar daha hızlıdır çünkü closure’lar sadece fonksiyon içerisinde yaşamaktadır ve bu da Swift’in optimizasyon yapmasına olanak tanır.
* Escaping closure’lar ise hafızada daha uzun süre tutulduğundan, performans kaybı yaşanabilir.
Ne Zaman Hangisini Kullanmalıyız?
Bu iki closure türü, farklı senaryolar için uygundur ve ne zaman hangi türün kullanılacağını anlamak, performans açısından çok önemlidir.
1. Eğer fonksiyonunuz asenkron bir işlem gerçekleştiriyorsa, "escaping" closure kullanmanız gerekir. Özellikle ağ istekleri ve uzun süreli işlemler için bu tür closure’lar oldukça yaygındır.
2. Eğer fonksiyonunuz senkron bir işlem yapıyorsa ve kapanışı hemen gerçekleştirebiliyorsa, "non-escaping" closure kullanmak daha verimli olur.
Performans ve Bellek Yönetimi İçin İpuçları
İyi bir yazılımcı olmak, sadece doğru kod yazmakla değil, aynı zamanda bu kodun verimli ve hatasız çalışmasını sağlamakla da ilgilidir. İşte bazı pratik ipuçları:
1. Güçlü Referans Döngülerinden Kaçının:
Eğer bir closure, bir nesneye güçlü bir referans tutuyorsa, bu durum hafıza sızıntılarına yol açabilir. Bu yüzden `weak` veya `unowned` referanslar kullanmaya özen gösterin.
2. Non-Escaping Closure’ları Tercih Edin:
Eğer asenkron işlem yapmanıza gerek yoksa, non-escaping closure’ları tercih edin. Hem bellek açısından daha verimli hem de performans açısından daha hızlıdır.
3. Kodunuzu İyi Test Edin:
Bellek yönetimi konusunda dikkatli olun. Özellikle büyük projelerde, bellek sızıntılarını takip etmek için araçlar kullanmak faydalıdır.
Sonuç
Swift'te "escaping" ve "non-escaping" closure’lar, hem performans hem de bellek yönetimi açısından büyük farklar yaratabilir. Bu iki tür arasındaki farkları anlamak ve doğru zamanda doğru türü kullanmak, Swift uygulamalarınızın hem daha verimli hem de daha güvenli olmasını sağlar. Unutmayın, yazılım geliştirmede her küçük detay, büyük farklar yaratabilir!