ProgramlamaiOS/Swift Geliştirici

Swift'te Initializer Delegation (başlatma delegasyonu) nedir, designated ve convenience başlatıcıları arasındaki delegasyon kuralları nasıl çalışır ve bu, miras almayı nasıl etkiler?

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

Cevap.

Initializer Delegation, Swift'te sınıflar için yerleşik bir başlatma delegasyonu sistemidir. Swift'te tarihsel olarak designated initializer (sınıfın tüm özelliklerini tam olarak başlatmaktan sorumlu olan ana başlatıcı) ve convenience initializer (farklı parametre setleriyle örnek oluşturmayı kolaylaştıran yardımcı başlatıcı) arasında bir ayrım vardır.

Sorun: Eğer sınıflar ve onların mirasçıları arasında başlatıcıların kaotik bir şekilde çalışmasına izin verilirse, temel sınıf tam olarak başlatılmadığı veya başlatma işleminin birden fazla kez gerçekleştiği durumlarla karşılaşmak mümkündür ki bu da geçersiz bir nesne ile sonuçlanır.

Çözüm — katı bir kural:

  1. Designated başlatıcı her zaman üst sınıfın designated başlatıcısını çağırır.
  2. Convenience başlatıcı her zaman aynı sınıftaki başka bir başlatıcıyı (designated veya başka bir convenience) çağırır.
  3. Convenience doğrudan üst sınıfı başlatamaz.

Kod örneği:

class Vehicle { var wheels: Int // Designated başlatıcı init(wheels: Int) { self.wheels = wheels } // Convenience başlatıcı convenience init() { self.init(wheels: 4) } } class Car: Vehicle { var color: String // Designated başlatıcı init(wheels: Int, color: String) { self.color = color super.init(wheels: wheels) } // Convenience başlatıcı convenience init(color: String) { self.init(wheels: 4, color: color) } }

Anahtar özellikler:

  • Farklı parametre setleri ile instance'lar oluştururken minimum kod tekrarı gereklidir.
  • Sınıfların güvenli mirasını destekler.
  • Nesnenin tüm özelliklerinin doğru bir şekilde başlatılmasını garanti eder.

Tuzak Sorular.

Soru 1: Convenience başlatıcı üst sınıfın başlatıcısını doğrudan super.init ile çağırabilir mi?

Hayır, convenience başlatıcı her zaman mevcut sınıftaki başka bir başlatıcıya (designated veya başka bir convenience) başvurur, bu başlatıcı daha sonra üst sınıfın designated başlatıcısını çağırabilir.

Soru 2: Eğer bir alt sınıfta required başlatıcı uygulanmazsa ne olur?

Eğer üst sınıfın required başlatıcısı varsa, bu her alt sınıfta (required kullanarak) geçersiz kılınmalıdır, aksi takdirde derleyici hata verecektir.

Soru 3: convenience init ile convenience required init arasındaki fark nedir?

convenience required init belirli bir convenience başlatıcısının üst sınıfta required olarak tanımlandığı durumlarda gereklidir, bu sayede miras hiyerarşisinde başlatmayı destekler.

Tipik Hatalar ve Anti-örnekler

  • Convenience/init çağrıları arasında yanlış bir zincirleme ve özelliklerin başlatılmasında ihlal.
  • Alt sınıfta required başlatıcıyı uygulamayı unuttular.
  • Convenience'den super.init çağırmaları, bu geçerli değildir.

Gerçek Hayat Örneği

Negatif Durum

Geliştirici convenience başlatıcısından super.init'i çağırdı. Kod yalnızca belirli kısıtlamaların olmaması sayesinde derlendi, ancak çalıştırma anında hata meydana geldi: nesnenin tüm özellikleri başlatılmamıştı.

Artıları:

  • Kod, diğer dillerdeki benzer uygulamaları anımsattığı için yeni başlayanlar için anlaşılır görünüyordu.

Eksileri:

  • Miras alımlarda hatalar ortaya çıktı — alt sınıflar düzgün bir şekilde başlatılmadı, uygulama çöküyordu.
  • Yeniden yapılandırılması gerekiyordu.

Pozitif Durum

Belirgin bir yapılandırılmış designated ve convenience başlatıcılarının net çağrıları kullanıldı. Mantık, Swift kurallarına sıkı sıkıya bağlı şekilde çağrıldı, bu nedenle başlatma her zaman şeffaf ve doğru oldu.

Artıları:

  • Sınıf hiyerarşisini genişletmek ve sürdürmek kolaydı.
  • Tekrarlayan kod hariç tutuldu.
  • Test etmeyi basitleştirdi.

Eksileri:

  • Büyük hiyerarşilerde başlatıcıların mirasının dikkatlice belgelenmesi gerekti.