3

如何找出结果的类型objc_msgSend

从文档:

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

也就是说,objc_msgSend返回的一切都是id类型,对吧?但有时该函数返回一个正确的 Objective C 对象(当请求 NSWindow +new 时),有时它只返回一个 bool (它是一个 C char)。

如何区分这些不同的结果?我如何知道它返回的是对象还是原始类型?

编辑:感谢您的回复!还有一个问题:是否至少可以判断返回的类型是原始类型还是适当的对象(然后可能通过 查询它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是否等于“@”。如果是,则返回类型为 type id您可以在此处查看对不同类型编码的引用,以及我在此处提到的 ObjC 运行时 API 方法。

正如 H2C03 所提到的,当推断出的返回类型表明它们的使用是合适的时(例如,当返回类型是结构或浮点数时,应该使用objc_msgSend_fpretand变体。请参阅 ObjC 运行时 API 文档上关于这两种方法的文档说明页。)objc_msgSend_stretmethod_getReturnType

另外,因为我希望你有一个美好的一天,我觉得我应该警告你运行时代码发现通常有点脆弱,通常是一种令人讨厌的性能气味。无论如何。:)

于 2012-07-01T21:49:29.903 回答