defer operatörü, kodun mevcut kapsamdan çıkmadan önce çalışmasını erteler, genellikle bir işlevden çıkarken. Kaynakları temizlemek, dosyaları kapatmak ve bellek serbest bırakmak için uygundur — bu, otomatikleşmiş bir cleanup olarak adlandırılır.
Özellikler:
Örnek:
func processFile() { let file = openFile() defer { closeFile(file) } // Dosya ile çalışma // file, throw veya return durumunda bile kapatılacak }
Tipik Olmayan Kullanım: 'finally' türü yapıların kısmi taklidi, günlükleme ve çalışma sürelerini izleme için kod gruplama.
Eğer uygulama, işlevin yürütülmesi sırasında kapanırsa defer çalışacak mı?
— Hayır. Defer, yalnızca kapsamın normal bir şekilde sona ermesinde (return, throw veya normal çıkış) çalışır. Uygulama acil bir kapanış yaparsa (örneğin, SIGKILL sinyali veya fatalError nedeniyle), defer blokları çalışmaya yetişmez.
Örnek:
func foo() { defer { print("Temizlik yap") } fatalError("Çökme!") // defer çalışmayacak }
Hikaye
Socket'lerle çalışan bir işlev, bir hata fırlatıldığında bağlantıyı temizlemedi. Veriler asılı kaldı, bağlantılar serbest bırakılmadı. Defer ekledikten sonra her şey doğru çalıştı: kaynaklar her zaman kapatıldı.
Hikaye
Geliştirici, küresel durumu serbest bırakmak için defer'e güvenmek istedi. fatalError oluştuğunda kaynak serbest bırakılmadı, bu da servislerde kilitlenmelere ve yeniden başlatma gereksinimlerine yol açtı.
Hikaye
Bir işlevde birden fazla defer ilan edildi ve bunların ilan sırasına göre çalışacağı düşünülüyordu. Sonuç olarak, kaynaklar yanlış sırayla kapatıldı (örneğin, önce dosya tanımlayıcı kapatıldı, sonra buna erişim sağlanmaya çalışıldı). Çözüm: defer bloklarının LIFO çalıştırılma sırasını hatırlamak.