ドキュメントから
安全チェック1
指定された初期化子は、スーパークラスの初期化子に委譲する前に、そのクラスによって導入されたすべてのプロパティが初期化されていることを確認する必要があります。
なぜこのような安全チェックが必要なのですか?
これに答えるために、初期化プロセスを迅速に行ってみましょう。
2フェーズ初期化
Swiftでのクラスの初期化は2段階のプロセスです。最初のフェーズでは、格納された各プロパティに、それを導入したクラスによって初期値が割り当てられます。すべての格納されたプロパティの初期状態が決定されると、第2フェーズが開始され、新しいインスタンスが使用可能になる前に、各クラスに格納されたプロパティをカスタマイズする機会が与えられます。
2フェーズの初期化プロセスを使用すると、初期化が安全になり、クラス階層内の各クラスに完全な柔軟性が提供されます。2フェーズの初期化により、プロパティ値が初期化される前にアクセスされたり、別のイニシャライザによって予期せずにプロパティ値が別の値に設定されたりすることが防止されます。
したがって、2つのステップの初期化プロセスが上記のように実行されたことを確認するために、4つの安全性チェックがあり、そのうちの1つは、
安全チェック1
指定された初期化子は、スーパークラスの初期化子に委譲する前に、そのクラスによって導入されたすべてのプロパティが初期化されていることを確認する必要があります。
現在、2フェーズの初期化では順序について話しませんが、この安全性チェックでsuper.init
は、すべてのプロパティの初期化後に順序付けが行われます。
安全チェック1は、2段階の初期化により、プロパティ値が初期化される前にアクセスできなくなるため、この安全チェック1がなくても満たすことができるため、無関係であると思わ
れる場合があります。
このサンプルのように
class Shape {
var name: String
var sides : Int
init(sides:Int, named: String) {
self.sides = sides
self.name = named
}
}
class Triangle: Shape {
var hypotenuse: Int
init(hypotenuse:Int) {
super.init(sides: 3, named: "Triangle")
self.hypotenuse = hypotenuse
}
}
Triangle.init
使用する前に、すべてのプロパティを初期化しました。安全チェック1は関係ないようです。
しかし、少し複雑な別のシナリオが考えられます。
class Shape {
var name: String
var sides : Int
init(sides:Int, named: String) {
self.sides = sides
self.name = named
printShapeDescription()
}
func printShapeDescription() {
print("Shape Name :\(self.name)")
print("Sides :\(self.sides)")
}
}
class Triangle: Shape {
var hypotenuse: Int
init(hypotenuse:Int) {
self.hypotenuse = hypotenuse
super.init(sides: 3, named: "Triangle")
}
override func printShapeDescription() {
super.printShapeDescription()
print("Hypotenuse :\(self.hypotenuse)")
}
}
let triangle = Triangle(hypotenuse: 12)
出力:
Shape Name :Triangle
Sides :3
Hypotenuse :12
ここで、をsuper.init
設定する前hypotenuse
にをsuper.init
呼び出した場合、呼び出しはを呼び出しprintShapeDescription()
、それがオーバーライドされているため、最初にのTriangleクラス実装にフォールバックしprintShapeDescription()
ます。printShapeDescription()
トライアングルクラスのアクセスのhypotenuse
まだ初期化されていないこと以外、オプションのプロパティ。また、2フェーズの初期化では、初期化される前にプロパティ値にアクセスできないため、これは許可されません。
したがって、2フェーズの初期化が定義どおりに行われていることを確認してください。特定の呼び出し順序が必要です。つまりsuper.init
、self
クラスによって導入されたすべてのプロパティを初期化した後、安全チェックが必要です1