27

C++/Java/C# のバックグラウンドから来て、Swift で仮想メソッドが表示されることを期待していましたが、Swift のドキュメントを読んでも、仮想メソッドについては言及されていません。

私は何が欠けていますか?


閲覧数が多いため、最新かつ非常に明確で詳細な回答に対して報酬を提供することにしました。

4

6 に答える 6

21

C++ とは異なり、Swift ではメソッドが仮想であることを指定する必要はありません。コンパイラは、次のうちどれを使用するかを決定します。

(もちろん、パフォーマンス メトリックはハードウェアに依存します)

  • メソッドのインライン化: 0 ns
  • 静的ディスパッチ: < 1.1ns
  • 仮想ディスパッチ 1.1ns (指定された場合は Java、C#、C++ など)。
  • 動的ディスパッチ 4.9ns (Objective-C など)。

もちろん、Objective-C は常に後者を使用します。4.9ns のオーバーヘッドは通常、メソッドの実行時間全体のごく一部にすぎないため、問題にはなりません。ただし、必要に応じて、開発者は C または C++ にシームレスにフォールバックできます。ただし、Swift では、コンパイラは最速のものを使用できるかを分析し、インライン、静的、および仮想を優先しながら、Objective-C の相互運用性のためのメッセージングを保持して、ユーザーに代わって決定しようとします。dynamicメッセージングを促進するために、メソッドを でマークすることができます。

これの副作用の 1 つは、動的ディスパッチによって提供される強力な機能の一部が利用できない可能性があることです。動的ディスパッチはメソッド インターセプトに使用され、次のように使用されます。

  • ココア スタイルのプロパティ オブザーバー。
  • CoreData モデル オブジェクトのインストルメンテーション。
  • アスペクト指向プログラミング

上記の機能の種類は、late binding言語によって提供される機能です。Java はメソッド呼び出しに vtable ディスパッチを使用しますが、依然として遅延バインディング言語と見なされているため、仮想マシンとクラス ローダー システムを使用することで上記の機能を実行できることに注意してください。これは、ランタイム インストルメンテーションを提供する別のアプローチです。「純粋な」Swift (Objective-C 相互運用なし) は、静的ディスパッチを使用して直接実行可能なコンパイル済み言語であるという点で C++ に似ており、これらの動的機能は実行時に使用できません。ARC の伝統では、これらの種類の機能がコンパイル時に移行する可能性があります。これにより、モバイル コンピューティングで重要な考慮事項である「ワットあたりのパフォーマンス」に関して優位性が得られます。

于 2014-08-22T01:23:46.420 に答える
7

すべてのメソッドは仮想です。overrideただし、キーワードを使用して基本クラスからメソッドをオーバーライドしていることを宣言する必要があります。

Swiftプログラミングガイドから:

オーバーライド

サブクラスは、そうでなければスーパークラスから継承するインスタンス メソッド、クラス メソッド、インスタンス プロパティ、またはサブスクリプトの独自のカスタム実装を提供できます。これはオーバーライドと呼ばれます。

他の方法では継承される特性をオーバーライドするには、オーバーライド定義の前にoverrideキーワードを付けます。そうすることで、オーバーライドを提供するつもりであり、誤って一致する定義を提供していないことが明確になります。誤ってオーバーライドすると、予期しない動作が発生する可能性があり、キーワードのないオーバーライドはoverride、コードのコンパイル時にエラーと診断されます。

このoverrideキーワードは、Swift コンパイラに、オーバーライド クラスのスーパークラス (またはその親の 1 つ) に、オーバーライドに指定したものと一致する宣言があることを確認するように促します。このチェックにより、上書き定義が正しいことが保証されます。

于 2014-06-03T11:52:53.523 に答える
-2

Swift は、Objective-C プログラマーが簡単に習得できるように作成されました。Objective-C には、仮想メソッドはありません。少なくとも、皆さんが考えるような方法ではありません。SO で Objective-C で抽象クラスまたは仮想メソッドを作成する方法についての説明を探している場合、通常は例外をスローしてアプリをクラッシュさせる通常のメソッドです。(仮想メソッドを呼び出すことは想定されていないため、これは理にかなっています)

したがって、Swift のドキュメントが仮想メソッドについて何も述べていない場合、私の推測では、Objective-C と同様に、仮想メソッドはありません。

于 2014-06-03T11:47:56.723 に答える