ProgrammingシニアiOS開発者

Swiftではプロパティの初期化はどのように実現されますか?designated、convenience、およびrequiredイニシャライザはどのように異なりますか?初期化の階層で作業する際にどのようなニュアンスが生じますか?

Hintsage AIアシスタントで面接を突破

回答。

Swiftでは、すべての非optionalタイプのプロパティはインスタンスの初期化が完了する前に初期化される必要があります。そのために、designated(主要)、convenience(補助)、およびrequired(継承者に必須)イニシャライザが使用されます。

  • Designatedイニシャライザ — これは主要なもので、クラスのすべてのプロパティを初期化し、スーパークラスのdesignatedイニシャライザを呼び出す役割を担います。各クラスには少なくとも1つのdesignatedイニシャライザがあります。
  • Convenienceイニシャライザ — これは補助的なもので、この同じクラスに初期化を委任します(self.init(...)を介してクラス内の他のイニシャライザを呼び出します),異なるパラメータセットを使用してオブジェクトの作成を簡素化します。
  • Requiredイニシャライザ — これはすべてのサブクラスがこのイニシャライザを実装することを要求します。required修飾子で宣言されます。

例:

class Vehicle { let numberOfWheels: Int required init(numberOfWheels: Int) { self.numberOfWheels = numberOfWheels } } class Car: Vehicle { let brand: String // Designated イニシャライザ required init(numberOfWheels: Int) { self.brand = "Unknown" super.init(numberOfWheels: numberOfWheels) } // Convenience convenience init() { self.init(numberOfWheels: 4) self.brand = "Ford" } }

主なポイント:

  • すべてのプロパティはsuper.initへの呼び出し前に初期化されなければなりません。
  • Convenienceイニシャライザは常にdesignatedまたは他のconvenienceイニシャライザselfを呼び出す必要があります。
  • Requiredイニシャライザはすべてのサブクラスで実装される必要があります。

ひねりのある質問。

designatedイニシャライザを使用する際、サブクラスとスーパークラスのプロパティを初期化する順序はどうなるべきですか?

**回答:**サブクラスのすべてのプロパティは、スーパークラスのdesignatedイニシャライザ(super.init)を呼び出す前に初期化される必要があります。そうしないとコンパイルエラーになります。super.initの後には、サブクラスの新しいstoredプロパティを初期化することはできず、それらを使用するだけです。

class Parent { let parentProp: Int init(prop: Int) { parentProp = prop } } class Child: Parent { let childProp: String init(prop: Int, childProp: String) { self.childProp = childProp // まず自分のプロパティを super.init(prop: prop) // 次に親を } }

テーマの細かい点を知らないための実際のエラーの例。


物語

開発者がconvenienceイニシャライザ内で、designatedを呼び出さずにrequireプロパティに直接値を割り当てようとしました。その結果、プロパティは異なる値で2回初期化され、テスト時に予期しない動作を引き起こしました。


物語

深いクラス階層の継承時にrequired initを宣言し忘れ、その結果、リフレクションを介して派生タイプを正しく初期化できなくなり、JSONモデルのデシリアライズ時にクラッシュしました。


物語

Vehicleクラスを拡張する際にスーパークラスのdesignatedイニシャライザが呼び出されなかったため、必須のプロパティの初期化が不正となり、データスキーマ更新後に運用中にクラッシュを引き起こしました。