defer, bir işlevin kapsamından (scope) çıkmadan önce belirli bir kod bloğunu çalıştırmayı sağlayan özel bir Swift yapısıdır; bu, normal bir return ile veya hata (throw) ile çıkmış olsanız da alakalı değildir. Defer kaynakları serbest bırakmak, değişiklikleri iptal etmek veya işlemleri tamamlamak için kullanışlıdır.
Çalışma Özellikleri:
Örnek:
func testDefer() { print("başlangıç") defer { print("ilk defer") } defer { print("ikinci defer") } print("bitiş") } // Çıktı: // başlangıç // bitiş // ikinci defer // ilk defer
Köşe Koşulları:
Eğer içinde fatalError çağrılırsa, işlevdeki tüm defer blokları çalıştırılacak mı?
Cevap: Hayır, eğer işlevde fatalError (veya benzeri kontrol edilemeyen çökmeler) çağrılırsa, tüm defer ile ertelenmiş bloklar çalıştırılmaz. defer, uygulamanın acil bir şekilde sonlandığı durumlarda kodun çağrılmasını garanti etmez.
Örnek:
func foo() { defer { print("Defer 1") } fatalError("Aman Tanrım") defer { print("Defer 2") } } foo() // hiçbir şey yazdırmayacak, çökme gerçekleşecek
Hikaye
Projede dosya tanıtıcılarını kapatmak için defer kullanıldı. Hata meydana geldiğinde fatalError yerine doğru bir throw kullanmadıkları için, crash durumunda defer çalışmadığından açık kaynak sızıntısına yol açtı.
Hikaye
Bir işlevde birkaç defer vardı, bazıları yerel değişkenlerin durumuna bağımlıydı. Geliştirici, değişkenin belirli bir değere eşit olmasını bekliyordu, ancak bu değer defer'de başka bir kod parçası tarafından değiştirildi ve defer çalıştığında güncel, eski değil, değer kullanıldı, bu da yanlış ID ile işlemin iptal edilmesine neden oldu.
Hikaye
İç içe bir closure içinde bir defer bloğu yazdılar ve bunun dış işlevden çıkarken çalışacağını düşündüler. Sonuçta bu defer, tüm işlevden çıkarken değil, closure'den çıkarken yürütüldü ve kaynak çok erken serbest bırakıldı.