メソッドを@objcとdynamicとしてマークすることの違いは何ですか?
以下は、ダイナミックに関するAppleの定義です。
dynamicこの修飾子を、Objective-Cで表現できるクラスのメンバーに適用します。 dynamic修飾子を使用してメンバー宣言をマークすると、そのメンバーへのアクセスは常にObjective-Cランタイムを使用して動的にディスパッチされます。そのメンバーへのアクセスは、コンパイラーによってインライン化または仮想化されることはありません。
Dynamic修飾子でマークされた宣言はObjective-Cランタイムを使用してディスパッチされるため、暗黙的にobjc属性でマークされます。
@objc
として宣言された関数/変数はObjective-Cからアクセスできますが、Swiftは静的または仮想ディスパッチを介して直接アクセスし続けます。これは、関数/変数がスウィズルされている場合Key-Value ObservingまたはさまざまなObjective-C APIを使用してクラスを変更し、SwiftとObjective-Cからメソッドを呼び出すと異なる結果が生成されます。
dynamic
を使用すると、Swiftは常にObjective-Cの動的ディスパッチを参照します。これは、Key-Value Observingなどが正しく機能するために必要です。Swift関数が呼び出され、Objective-Cランタイムを参照して、呼び出しを動的にディスパッチします。
その引用が言うように、dynamic
は@objc
。
クラスをdynamic
として指定しない限り、コンパイラはメソッドを自由に最適化し、インライン化できます。これにより、パフォーマンスが大幅に向上しますが、実行時にこれらのメソッドの実装を変更できないことを意味します。 Objective Cランタイムのリフレクション機能を使用して、実行時にこれらのメソッドをいじることを計画している場合は、dynamic
を使用する必要があります。パフォーマンスが低下します(コードはCに近いレベルではなく、Objective Cレベルの速度で実行されます)が、余分なダイナミズムが得られます。
相互運用性を扱う際に留意すべき2つのキーワードがあります。
@objc
は、Objective-CからSwiftコード(クラス、メソッド、プロパティなど)が見えるようにすることを意味します。dynamic
は、 Objective-C動的ディスパッチを使用することを意味します。Swift 3以前では、dynamic
も@objc
。 Swift 4、dynamic
の新機能は、動的ディスパッチのみを意味し、Objective-Cの可視性については何も言及していません。
ただし、Swift動的ディスパッチなどはありません。 Objective-Cランタイムの動的ディスパッチのみがあります。つまり、動的なものだけではなく、@objc dynamic
。したがって、これは事実上、以前と同じ状況であり、明示しただけです。
続きを読む こちら