2016-11-24 9 views
22

メソッドを@objcと動的に区別する方法の違いは何ですか?Swift 3 - dynamic vs @objc

以下は、Appleの動的定義です。

dynamic Objective-Cで表される のクラスのメンバーにこの修飾子を適用します。 という動的修飾子を持つメンバー宣言をマークすると、そのメンバーへのアクセスはObjective-Cランタイムを使用して常に動的に にディスパッチされます。そのメンバへのアクセスは、 であり、コンパイラによってインライン化されたり、デバッグされたりすることはありません。

動的変更子でマークされた宣言は、Objective-Cランタイムを使用して を送出するため、暗黙のうちにobjc 属性でマークされます。

+0

質問に回答しましたか? – Alexander

答えて

26

@objcとして宣言された関数/変数はObjective-Cからアクセスできますが、Swiftは静的または仮想ディスパッチを介して直接アクセスし続けます。 これは、Key-Value ObservingやさまざまなObjective-C APIを使用してクラスを変更した場合のように、Objective-Cフレームワークで関数/変数をスウィズルした場合、SwiftとObjective-Cからメソッドを呼び出すと異なる結果が生成されることを意味します。

dynamicを使用すると、Swiftは常にObjective-Cの動的ディスパッチを参照します。 これは、Key-Value Observingが正しく機能するために必要です。 Swift関数が呼び出されると、それはObjective-Cランタイムを参照して呼び出しを動的にディスパッチします。

+0

私はKVOがうんざりしているのを知らなかった、この点について詳しく説明できますか? – Boon

+2

@Boon KVOは動的サブクラスを作成し、automaticallyNotifiesObserversForKeyがオプトアウトに使用されない限り、プロパティをwillChangeValueForKey/didChangeValueForKey呼び出しでラップされたものに置き換えます。 – kevin

6

この引用符で示されるように、dynamic@objcを意味します。

クラスをdynamicとして指定しない限り、コンパイラはそのメソッドを最適化してインライン化することは自由です。これにより、パフォーマンスが大幅に向上しますが、実行時にこれらのメソッドの実装を変更することはできません。 Objective Cランタイムのリフレクション機能を使用して実行時にこれらのメソッドを使いこなす場合は、dynamicを使用する必要があります。パフォーマンス上のペナルティが発生します(コードはObjective Cのレベルではなく、Cのようなレベルで実行されます)が、その余分なダイナミズムが得られます。

関連する問題