質問: XCodeでUIViewのサブクラスを作る際にrequire init()が必要な場合と必要ない場合はどのようなときでしょうか? ``` import UIKit class MyUIView:UIView { required init(coder aDecoder: NSCoder!) { super.init(coder: aDecoder) } } ``` 同じUIViewのサブクラスでもrequired init()がない場合もあります。 必要な場合と必要で無い場合を教えていただけないでしょうか?
回答: 簡単な答えとしては、「サブクラスで `convenience` でない `init` を実装する場合は必要。実装しない場合は必要ではない」です。 正確には を完全に理解する必要があるのですが、 > > Unlike subclasses in Objective-C, Swift subclasses do not inherit their superclass initializers by default. > > > Swift では、スーパークラスのイニシャライザを継承しないときがあります。というかデフォルトでは継承しません。 ですが、上記ドキュメントのAutomatic Initializer Inheritanceの項 > > **ルール1** > > サブクラスでDesignatedイニシャライザを定義しない場合はスーパークラスのすべてのDesignatedイニシャライザを継承します。 > > > とあります。 `UIView` には 2 つのDesignatedイニシャライザがあり `init(frame:)` と `init?(coder:)` です。 また、`init?(coder:)` は `required` 指定されています。 `init(frame:)` をオーバーライド**しない**場合は、`init?(coder:)`を実装しなくても継承されるのですが、実装**する**場合は、`init?(coder:)` は継承されずに、無くなってしまいます。ところが、`init?(coder:)` は `required` 指定なので定義されていないとコンパイルが通りません。なので、カスタムの動作を加える否かに関わらず、実装しないとダメということになります。 逆に、`init?(coder:)` だけを実装することは可能なのですが、`init(frame:)` は継承されないので、下記コードはコンパイルできません。 ``` class MyView : UIView { required init?(coder aDecoder: NSCoder) { super.init(coder: aDecoder) } } MyView(frame: CGRectZero) // init(frame:) が無い! ``` ※ Xcode7 で `init(coder:)` は Failable initializer となったので `init?(coder:)` としています。