如何查找objc_msgSend结果的类型
从文档中:
id objc_msgSend(id theReceiver, SEL theSelector, ...)也就是说,objc_msgSend返回的所有内容都是id类型的,对吧?但有时该函数会返回一个适当的Objective C对象(当请求NSWindow +char时),而有时它只返回一个布尔值(这是一个C new)。
如何区分这些不同的结果?我怎么知道它返回的是一个对象还是一个原始类型?
编辑:感谢您的回复!还有一个问题:至少可以判断返回的类型是原始类型还是正确的对象(然后可能通过object_getClass查询它)?
发布于 2012-07-02 05:49:30
如果这是返回类型的运行时发现,您可以使用ObjC运行时应用编程接口来查找给定对象方法的方法定义,然后查找返回类型。具体地说,方法:
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。您可以看到对不同类型编码here的引用,以及我提到的ObjC运行时here方法。
正如H2C03所提到的,当从objc_msgSend_fpret推断出的返回类型表明它们的使用是适当的时(例如,当返回类型是结构或浮点时),就应该使用objc_msgSend_stret和method_getReturnType变体。请参阅ObjC运行时API文档页面上关于这两种方法的文档说明。)
此外,因为我希望您有一个好的一天,我觉得我应该警告您运行时代码发现通常是有点脆弱,通常是令人讨厌的性能气味。不管怎么说。:)
发布于 2012-07-02 05:36:49
objc_msgSend的调用者应该已经知道返回的类型,并且必须将objc_msgSend有效地强制转换为返回正确值的函数指针类型。例如,可以像这样手动调用-[NSString UTF8String]:
const char *cStr = ((const char *(*)(id, SEL))objc_msgSend)
(@"foo", @selector(UTF8String));是的,相当长,这就是为什么让编译器来做通常是一个更好的主意。如果您在发送消息时需要更多的动态性,我建议您首先查看NSInvocation。其中,用于初始化调用的方法签名将包括有关返回类型和所有参数的信息。
发布于 2012-07-02 05:36:38
您只能从方法签名中知道它。此外,当返回浮点数、objc_msgSend_fpret和返回结构时,将使用objc_msgSend_stret。
如果返回值是Objective-C对象,则可以使用object_getClass()查询它的类。
https://stackoverflow.com/questions/11285780
复制相似问题