web-dev-qa-db-ja.com

Swift 3-動的vs @objc

メソッドを@objcとdynamicとしてマークすることの違いは何ですか?

以下は、ダイナミックに関するAppleの定義です。

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

Dynamic修飾子でマークされた宣言はObjective-Cランタイムを使用してディスパッチされるため、暗黙的にobjc属性でマークされます。

32
Boon

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

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

47
kevin

その引用が言うように、dynamic@objc

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

11
Alexander

相互運用性を扱う際に留意すべき2つのキーワードがあります。

Swift 3以前では、dynamic@objc。 Swift 4、dynamicの新機能は、動的ディスパッチのみを意味し、Objective-Cの可視性については何も言及していません。

ただし、Swift動的ディスパッチなどはありません。 Objective-Cランタイムの動的ディスパッチのみがあります。つまり、動的なものだけではなく、@objc dynamic。したがって、これは事実上、以前と同じ状況であり、明示しただけです。

続きを読む こちら

3
yoAlex5