3

結果のタイプを見つける方法はobjc_msgSend

ドキュメントから:

id objc_msgSend(id theReceiver, SEL theSelector, ...)

つまり、objc_msgSend返されるものはすべてidタイプですよね?ただし、関数が適切なObjective Cオブジェクトを返す場合(NSWindow + newを要求する場合)もあれば、ブール値(C char)のみを返す場合もあります。

それらのさまざまな結果をどのように区別するのですか?それがオブジェクトであるかプリミティブ型であるかをどのように知ることができますか?

編集:返信ありがとうございます!もう1つの質問:返された型がプリミティブなものなのか、適切なオブジェクトなのかを判断することは少なくとも可能ではありませんか(そしておそらくそれをクエリすることによってobject_getClass)?

4

3 に答える 3

8

の呼び出し元objc_msgSendは、返される型をすでに知っていることが期待されておりobjc_msgSend、正しい値を返す関数ポインタ型に効果的にキャストする必要があります。たとえば、次の-[NSString UTF8String]ように手動で呼び出されます。

const char *cStr = ((const char *(*)(id, SEL))objc_msgSend)
    (@"foo", @selector(UTF8String));

はい、かなり一口です。そのため、通常はコンパイラに実行させる方がよいでしょう。メッセージの送信にさらにダイナミズムが必要な場合は、最初にNSInvocationを確認することをお勧めします。特に、呼び出しが初期化されるメソッドシグネチャには、戻り型とすべての引数に関する情報が含まれます。

于 2012-07-01T21:36:48.627 に答える
5

メソッドシグネチャからのみ知ることができます。また、浮動小数点数をobjc_msgSend_fpret返すとき、および構造体を返すときは、objc_msgSend_stretが使用されます。

戻り値がObjective-Cオブジェクトの場合、を使用してそのクラスを照会できますobject_getClass()

于 2012-07-01T21:36:38.133 に答える
5

これが戻り型のランタイム検出である場合は、ObjCランタイムAPIを使用して、特定のオブジェクトメソッドのメソッド定義を検索してから、戻り型を検索できます。具体的には、方法は次のとおりです。

Method class_getInstanceMethod(Class aClass, SEL aSelector)

また

Method class_getClassMethod(Class aClass, SEL aSelector)

構造体を取得し、Method後でクエリを実行できます

void method_getReturnType(Method method, char *dst, size_t dst_len)

戻り型のcstring記述を取得します。この説明は人間が読める形式ではありません。たとえば、例を考えると、で参照されている文字列*dstが「@」に等しいかどうかを確認する必要があります。そうである場合、戻り型は型idです。ここでさまざまなタイプのエンコーディングへの参照と、ここで説明したObjCランタイムAPIメソッドを確認できます

H2C03で述べたように、objc_msgSend_fpretおよびobjc_msgSend_stretバリアントは、から推測されるリターンタイプmethod_getReturnTypeがそれらの使用が適切であることを示す場合に使用する必要があります(たとえば、リターンタイプが構造体またはフロートである場合。ObjCランタイムAPIドキュメントのこれら2つのメソッドに関するドキュメントノートを参照してください。ページ。)

また、良い一日を過ごしてほしいので、ランタイムコードの検出は通常少しもろく、通常は不快なパフォーマンスの臭いがあることを警告する必要があると思います。いずれかの方法。:)

于 2012-07-01T21:49:29.903 に答える