ProgramlamaiOS geliştiricisi

Swift'teki defer mekanizmasını, hangi köşe koşulları ve özelliklere dikkat edilmesi gerektiğini açıklayın.

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

Cevap.

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:

  • Eğer işlevde birden fazla defer varsa, bunlar ters sırayla çalışır (LIFO — last in, first out, yığın yapısı).
  • Defer, hata (throw) meydana geldiğinde veya işlevden herhangi bir return ile çıkıldığında bile çalışır.
  • Closure içinde defer, closure'ın çağrı yerinden ziyade closure'ın gövdesine aittir.

Ö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ı:

  • Defer, defer'in ortaya çıktığı anda değişkenlerin değerlerini yakalar: Eğer defer closure içinde değişkenler kullanıyorsanız, bunlardaki değişiklikler defer'in çalıştığı anda görülecektir.
  • Eğer işlev fatalError ile tamamlanırsa, defer çağrılmaz.

İkna edici bir soru.

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

Konunun inceliklerinden dolayı gerçek hata örnekleri.


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ı.