37267


objective-cでの下記のような初期化をしたい場合の書き方をSwiftにする場合、どのように記述したら良いでしょうか。

[code]

    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
    if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]))
    {
        // Custom initialization
        test = 0;
    }
    return self;
    }
    
[/code]


CC BY-SA 3.0
2017-08-17T03:49:11.130
37264
2017-08-17T05:18:12.113
2017-08-17T05:18:12.113
13972
14780
question
swift ios swift3
objective-cでの初期化をSwiftでの書き方について


Objective-
Cのイニシャライザの中には、Swiftからオーバライドすることは無理、と言うものもあるのですが、ご掲載のようなイニシャライザの場合は、基本パターン通りでSwift側でオーバライドできます。ただ、その「基本パターン」をわかりやすくまとめてある記事は意外と見つからなかったので、以下に説明させていただきます。

[code]

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        //(Phase1)この範囲で新規に導入されたプロパティをすべて初期化する
        // この間は`self`を(直接・間接を問わず)使用するコードを書いてはいけない
        test = 0 //<-`test`が初期化式のないプロパティだとすると、この文は`super.init(...)`より先に実行する必要がある
        //...
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
        //(Phase2)この範囲では`self`の使用を含めて初期化に必要な処理を記載できる
        //...
    }
    
[/code]

(`test`は、上記のイニシャライザを持つサブクラス側で新たに導入されたインスタンスプロパティと言う想定です。)

いくつかポイントを挙げておきます。

  * Objective-Cでパターン化している`if( (self = [super initXxx...]) ) {...}`と言うif文による判定はSwiftでは必要ありません。無視して、`super.init(Xxx...)`だけ呼んでください。

  * Swiftのイニシャライザの制約([このリンク先](https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID216)のTwo-Phase Initializationのあたりを参照してください、全部英語かつとてもわかりやすいとは言えませんが)により、新たに導入されたプロパティの初期化は`super.init(...)`を呼ぶ前に行っておく必要があります。

タグで[swift3]が指定されていましたが、上記事項は全てのバージョンのSwiftで共通事項です。  
(コード例はSwift3用。)

Swiftでは一つの(指定)イニシャライザをオーバライドすると、他のイニシャライザが自動継承されなくなりますので、上記のイニシャライザを正しくオーバライドすると、別問題が発生する可能性があります。「別問題」に関する質問が必要となった場合は、あらたな質問としてください。


CC BY-SA 3.0
2017-08-17T05:17:34.107
37267
2017-08-17T05:17:34.107
13972
37264
answer