我在测试工具中有以下 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)
根本无法编码函数类型——它只是返回"?"
或"^?"
。所以我想我不能从字面上使用@encode
.
但是有什么我可以做的吗?