19069


XCodeでUIViewのサブクラスを作る際にrequire init()が必要な場合と必要ない場合はどのようなときでしょうか？

[code]

    import UIKit
    
    class MyUIView:UIView
    {
        required init(coder aDecoder: NSCoder!) {
            super.init(coder: aDecoder)
        }
    }
    
[/code]

同じUIViewのサブクラスでもrequired init()がない場合もあります。  
必要な場合と必要で無い場合を教えていただけないでしょうか？


CC BY-SA 3.0
2015-11-03T13:02:50.183
18367
2015-11-20T06:12:14.193
8593
question
swift xcode
UIViewのサブクラス時にrequire init()が必要な場合の理由


簡単な答えとしては、「サブクラスで `convenience` でない `init` を実装する場合は必要。実装しない場合は必要ではない」です。

正確には  
<https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html>
を完全に理解する必要があるのですが、

> 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:)`
は継承されないので、下記コードはコンパイルできません。

[code]

    class MyView : UIView {
        required init?(coder aDecoder: NSCoder) {
            super.init(coder: aDecoder)
        }
    }
    
    MyView(frame: CGRectZero) // init(frame:) が無い！ 
    
[/code]

※ Xcode7 で `init(coder:)` は Failable initializer となったので `init?(coder:)`
としています。


CC BY-SA 3.0
2015-11-20T04:50:11.670
19069
2015-11-20T06:12:14.193
2015-11-20T06:12:14.193
3489
3489
18367
answer