ProgramlamaKıdemli iOS Geliştirici

Swift'te özelliklerin nasıl başlatıldığını nasıl gerçekleştirilir? Designated, convenience ve required başlatıcıları arasındaki farklar nelerdir? Başlatma hiyerarşileri ile çalışırken hangi nüanslar ortaya çıkar?

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

Cevap.

Swift'te tüm optional olmayan türdeki özellikler, bir nesnenin başlatılması sona ermeden önce başlatılmalıdır. Bunun için üç tür başlatıcı kullanılır: designated (temel), convenience (yardımcı) ve required (miras alanlar için zorunlu).

  • Designated başlatıcı — ana başlatıcı, sınıfın tüm özelliklerinin başlatılmasından ve üst sınıfın designated başlatıcısının çağrılmasından sorumludur. Her sınıfın en az bir designated başlatıcısı vardır.
  • Convenience başlatıcılar — yardımcı başlatıcılardır, bu aynı sınıfta başlatmayı devrederek (self.init(...) ile içindeki diğer başlatıcıları çağırarak) farklı parametre setleri ile nesne oluşturmayı kolaylaştırır.
  • Required başlatıcı — tüm alt sınıfların bu başlatıcıyı uygulamasını gerektirir. required anahtar kelimesi ile bildirilir.

Örnek:

class Vehicle { let numberOfWheels: Int required init(numberOfWheels: Int) { self.numberOfWheels = numberOfWheels } } class Car: Vehicle { let brand: String // Designated başlatıcı required init(numberOfWheels: Int) { self.brand = "Unknown" super.init(numberOfWheels: numberOfWheels) } // Convenience convenience init() { self.init(numberOfWheels: 4) self.brand = "Ford" } }

Anahtar özellikler:

  • Tüm özellikler super.init'e erişmeden önce başlatılmalıdır.
  • Convenience başlatıcılar her zaman self ile başka bir designated veya convenience başlatıcıyı çağırmalıdır.
  • Required başlatıcılar tüm miras alanlar tarafından uygulanmalıdır.

Kandırmaca Soru.

Designated başlatıcısını kullanırken alt sınıf ve üst sınıf özelliklerini hangi sırayla başlatmak gerekir?

Cevap: Alt sınıfın tüm özellikleri super.init çağrısından önce başlatılmalıdır, aksi takdirde bir derleme hatası oluşur. Super.init'den sonra alt sınıfın yeni stored özelliklerini başlatmak mümkün değildir, yalnızca kullanmaları gerekir.

class Parent { let parentProp: Int init(prop: Int) { parentProp = prop } } class Child: Parent { let childProp: String init(prop: Int, childProp: String) { self.childProp = childProp // Önce kendi özelliklerim super.init(prop: prop) // Sonra parent } }

Konuyla ilgili bilgi eksikliğinden kaynaklanan gerçek hata örnekleri.


Hikaye

Bir geliştirici convenience başlatıcısında doğrudan required özelliğe değer atamaya çalıştı, designated'i çağırmadan. Sonuç olarak, özellik iki farklı değerle başlatıldı ve test aşamasında beklenmedik davranışa yol açtı.


Hikaye

Derin sınıf hiyerarşisi miras alırken required init bildirememek, çerçeve üzerinden türetilen tipin düzgün başlatılamamasına ve JSON modelinin serileştirildiğinde çökmesine neden oldu.


Hikaye

Vehicle sınıfında genişletme sırasında üst sınıfın designated başlatıcısı çağırılmadı, bu zorunlu özelliklerin düzgün başlatılmamasına ve üretimde veri şemasının güncellenmesinden sonra runtime çökmesine yol açtı.