3

クレイジーな低レベル コードのテスト ハーネスに次の Objective-C コードがあります (質問しないでください)。

/* This category is declared here but not defined anywhere.
 * It lets me write
 *   id MyNewClass = objc_lookUpClass("MyNewClass");
 *   [MyNewClass class_method];
 * without spurious compiler warnings.
 */
@interface NSObject (MyNewClass)
+(void) class_method;
+(void) class_method_taking_int: (int) f;
-(int) method_returning_int: (int) i;
@end

...
{
    Class MyNewClass = objc_allocateClassPair([NSObject class], "MyNewClass", 0);
    Class MyNewClass_meta = object_getClass(cls);
    class_addMethod(MyNewClass_meta, @selector(class_method),
        (IMP)..., "v@:");
    class_addMethod(MyNewClass_meta, @selector(class_method_taking_int:),
        (IMP)..., "v@:i");
    class_addMethod(MyNewClass, @selector(method_returning_int:),
        (IMP)..., "i@:i");
    objc_registerClassPair(MyNewClass);
}

これらのリテラルなどをすべて排除できるようにしたいと思い"v@:i"ます。結局のところ、これらはNSObject (MyNewClass)カテゴリにリストされているメソッド シグネチャのエンコーディングに過ぎないはずです。だから私は次のようなものを書くことができるはずだと感じています

    class_addMethod(MyNewClass_meta, @selector(class_method_taking_int:),
        (IMP)..., @encode(__typeof__(+[NSObject class_method_taking_int:])));

もちろん、上記の構文は空想ですが、Objective-C にはこのようなものがあるべきではありませんか? そして、単純なマクロの背後にすべてを隠すことができ、コードはただ美しいものになります.

を使用できないことに注意してくださいmethodSignatureForSelector。これは、指定されたセレクターに応答するオブジェクトがあることを前提としているためです。クラスをまだ登録していないため、応答しません。

class_addMethodまた、 が期待する文字列の形式は、 が返す文字列の形式と同じではないことに注意してください@encode(foo)。実際には、@encode(foo)関数型をまったくエンコードできません。単に"?"orを返すだけ"^?"です。だから私は文字通り使用できないと思います@encode

しかし、私にできることはありますか?

4

0 に答える 0