私はさまざまなプログラミング言語と開発プラットフォームを比較しています。 Objective-Cと他の言語との重要な違いの1つは、セレクタ、メッセージを使用することで、毎回objc_msgSendを呼び出し、共有ライブラリの境界を越えて、測定可能なオーバーヘッドと、objc_msgSend http://www.mulle-kybernetik.com/artikel/Optimization/opti-3.html 私は専門家ではないので、私はこのフォーラムにあるこの記事を信頼しなければなりません。 公式のアップルのガイドで私は "ドットシンタックス"がちょうど "構文的な砂糖"であることがわかります、それは同じメソッド呼び出しメカニズムが使われています。 質問:クラスインスタンス内で純粋な呼び出しが実行されるかどうかを知りたい場合は、objc_msgSendを呼び出すのが無駄になります。つまり、1つのクラスインスタンスのメソッドが同じクラスインスタンスのメソッドから呼び出されたときです。 ありがとうobjective-c:セレクタまたは純粋な呼び出しでまだクラス内を呼び出すメソッドですか?
答えて
すべてのobjective-Cメソッド呼び出しでは、obj_msgSendが使用されます。これはコードが実際の実際のクラス(self
)を知らないためです。つまり、別の実装を持つサブクラスでも、たとえばxmlrpc経由でリモートマシンによって実装されるメソッドのプロキシでもかまいません。
AFAIKあなたは、メッセージXをオブジェクトYに頻繁に送信しようとしている場合、指定されたオブジェクトのセレクタの実装を取得することで、自分自身を最適化できます。
は、仮想的なOOP言語でこのような状況を考えてみましょう:
class A {
say_something(){
print("A!")
}
do_something(){
say_something()
}
}
と
class B : extends A {
say_something(){
print("B!")
}
}
は今、あなたはB
のインスタンスを持っていると仮定し、do_something
を呼び出す:
B b;
b.do_something();
万一b
A
またはを印刷? do_something
の実装におけるsay_something
の呼び出しがvtable
(C++)またはobj_msgSend
(Obj-C)の場合はB
と表示されますが、コンパイラが同じクラスのメソッドの呼び出しで同じクラスのメソッドであれば、A
を出力します。
これは望ましい状況によって異なります。したがって、C++では、メンバー関数virtual
をマークすることで、選択肢を持つことができます。 Objective-Cでは、すべてのメソッドが仮想です。
したがって、C++でも、提案した最適化は仮想メソッドには行われません。私は仮想メソッドなしで適切なOOP言語を言いません。
とにかく、Obj-Cアプリケーションのパフォーマンスが低下すると心配するかもしれません。 Appleは危険を知っているので、たくさんの最適化があります。たとえば、最近のランタイムではobjc_msgSend
が固定アドレスに存在するため、まず共有ライブラリの境界を通過する必要はありません。
ミュールキバネティックスの記事も素晴らしかったですが、それは非常に年代が古いことにも注意してください。これは10年前のことです。これは、このビジネスの前史時代です。 objc_msgSend
の実装に最近追加された最適化については、bbum's blog postsまたはHamster's blog postsで読むことができます。
UIを管理するコードを作成する場合は、標準のメッセージング(つまり、舞台裏でobjc_msgSend
)は完全に適切です。モバイル機器でも非常にスムーズに動作します。だから、コードの性能を測定した後で絶対に必要になるまで、IMP
などを取得して早すぎる最適化をしないでください。
たとえば、数万の粒子が動いている計算集約的なコードを書いているなら、私はObj-Cメッセージングフレームワークの使用についてアドバイスをします。その場合は、Objective-C++で使用できるCコード(Objective-Cでは常に使用可能)またはC++コード(Objective-C++で使用可能)を記述するだけです。
objc_msgSendおよびバリアントによる動的ディスパッチを引き続き使用します。
理想的には、JITに似たものがobjcタイプに対して生成されます。
にObjCとは異なり、C++コンパイラは ++、Cへの呼び出しのために、それはタイプを決定することができたときに仮想をマークされているタイプを静的ディスパッチを使用することができます。
どのような方法でも、最適化する方法はたくさんあります.C++で実装してから、objcを使うと便利ですが、正確に何を達成しようとしているのか分かりません。
- 1. スレッド内で純粋仮想メソッドを呼び出す
- 2. JNIメソッドから純粋なC関数を呼び出す
- 3. 具体的なクラスのメソッド呼び出しを呼び出す
- 4. オプションで純粋な関数で副作用を呼び出す
- 5. クラス内からメソッド内でメソッドを呼び出す方法
- 6. ObjectiveCからのコールバックでC++メソッドを呼び出す
- 7. Android :: Broadcasr Receiverクラスを呼び出すメソッドの呼び出し?
- 8. QThreadPoolは親クラスQRunnableの純粋仮想関数を呼び出します
- 9. 純粋仮想メソッド呼び出しエラーGoogleプロトコルバッファ
- 10. メソッド内でメソッドを呼び出すruby
- 11. クラス内の参照インスタンス変数またはメソッド呼び出し
- 12. creatorで呼び出されたメソッドは、基底クラスから呼び出されますが、派生クラスからは呼び出されません
- 13. 他のオブジェクトからメソッドを呼び出すメソッド呼び出し
- 14. クラスで静的メソッドを呼び出す?
- 15. クラス間で@selectorメソッドを呼び出す
- 16. クラスCでメソッドを呼び出す#
- 17. コンストラクタを呼び出さずにクラス内のメソッドを呼び出す
- 18. C#でメソッド/呼び出しを別のメソッドから呼び出す方法は?
- 19. Objective Cではメソッドを呼び出すクラスと、呼び出さないメソッドのみを呼び出す方法を教えてください。
- 20. defrecordコンストラクタで呼び出しを呼び出しますか?
- 21. 1回の呼び出しでメソッドを呼び出す
- 22. 各メソッド呼び出しでjQueryがコンストラクタを呼び出す
- 23. メソッドJavaクラスでの呼び出し
- 24. Javaでそのクラスを呼び出す前にメソッドを呼び出す
- 25. ObjectiveCではスーパークラスのメソッドを呼び出すタイミングが重要ですか?
- 26. 別のAPI呼び出し内でAPI呼び出しを行いますか?
- 27. 角度2のコンポーネントから純粋なjavascript関数を呼び出します。
- 28. メソッドからクラスを呼び出す
- 29. ビュー内でJqueryメソッドを呼び出す
- 30. メイン内でメソッドを呼び出す
IMPを参照してください。クラス内のすべての呼び出しでこれを行うのはどんな混乱ですか?しかし、コンパイラーはインスタンスがコンパイル時にそれ自身を呼び出すことを理解できませんか?非常に奇妙な。つまり、セレクタ構文を使用して同じインスタンスのメソッドを呼び出す必要はありません。 – P5music
@ P5music:C++の場合でも、クラスのメンバー関数の実装内部からのクラスの仮想メソッドの呼び出しは、仮想関数テーブルを経由します。 Objective-Cでは、すべてのメソッド呼び出しは仮想です。したがって、 'objc_msgSend'ファシリティを呼び出します。心配しないで、Appleは「objc_msgSend」が絶対に重要だと知っていますので、手作りのアセンブリとたくさんのハッキングを使って完全に調整するために多くの努力を払っています。 – Yuji