5

別のクラスからサブクラスを作成する場合override、関数に必要ですが、 「関数」init()をオーバーライドすることはできません。deinit

これはSwiftで可能ですか?

ここに例があります

class Foo {
    init(){
        print("Foo created")
    }

    deinit {
        print("Foo gone")
    }
}


class Bar: Foo {

    override init(){
        print("Bar created")
    }

    //Is not overwritten here
    deinit {
        print("Bar gone")
    }
}

サンプルビューコントローラーの内部

override func viewDidLoad() {
    super.viewDidLoad()

    var f: Foo?
    f = Foo()
    f = Bar()
    f = nil

}

出力

Foo created    //Foo object initialised - Foo init() called
Foo created    //Foo init() called before calling Bar init()? no call to superclass though..
Bar created    //Bar object initialised - Bar init() called
Foo gone       //Foo deinit called as Foo instance replaced by Bar instance
Bar gone       //Bar deinit called as Bar instance holds no references and is destroyed 
Foo gone       //Foo deinit called again as part of Bar object destruction?

拡張に関する私の元の質問に追加するにはdeinit

コード例では、オーバーライドによってスーパークラスの関数がinit()呼び出されるようです。init()これは何が起こっているのですか?

Barインスタンスが初期化解除されると、同じ動作が発生します。これもここで起こっていることですか?

4

1 に答える 1

9

deinitは通常のメソッドではないため、オーバーライドできません。すべてのインスタンスには、そのクラスとそのすべてのスーパークラスに対して1 つの独立したハンドラーがあります。 deinit

インスタンスの割り当て解除が行われる直前に、デイニシャライザが自動的に呼び出されます。deinitializer を自分で呼び出すことはできません。スーパークラスの初期化解除子はそのサブクラスによって継承され、スーパークラスの初期化解除子はサブクラスの初期化解除子の実装の最後に自動的に呼び出されます。サブクラスが独自の初期化解除子を提供しない場合でも、スーパークラスの初期化解除子は常に呼び出されます。

スーパークラスがその で行っていることを変更する理由はまったくないはずdeinitです。

とはなぜ違うのinitですか?イニシャライザでは、パラメータを渡す必要があり、実行順序も制御する必要があります ( の前super.init(...)のコード、 の後のコードsuper.init(...))。初期化解除は、実行順序が定義された自動プロセスです。オーバーライドは、不必要な問題を引き起こすだけでした。

于 2016-10-28T11:58:46.490 に答える