9

我理解的背景:Objective-C 方法调用基本上是一个带有两个隐藏参数(接收器和选择器)的 C 函数调用。Objective-C 运行时包含一个名为 objc_msgSend() 的函数,它允许以这种方式调用方法。不幸的是,当函数返回结构时,可能需要进行一些特殊处理。有一些神秘的(有些人可能会说是疯狂的)规则来控制结构是否像其他值一样返回,或者它是否实际上是通过隐藏的第一个参数中的引用返回的。对于 Objective-C 来说,在这些情况下必须使用另一个名为 objc_msgSend_stret() 的函数。

问题:给定一个方法,NSMethodSignature 或其他东西可以告诉我是否必须使用 objc_msgSend() 或 objc_msgSend_stret()?到目前为止,我们发现 NSMethodSignature 知道这一点,它会在调试输出中打印出来,但似乎没有公共 API。

如果您想回答“您到底为什么要这样做?!”,请在这样做之前阅读以下内容:https ://github.com/erikdoe/ocmock/pull/41

4

3 回答 3

0

NSMethodSignature有 a -methodReturnType,您可以检查以查看返回类型是否为 a struct。这是你想要做的吗?

于 2013-08-09T10:47:45.520 回答
0

Objective-C 在给定架构上为 C 使用相同的底层 ABI,因为方法只是带有隐式self_cmd参数的 C 函数。

换句话说,如果你有一个方法:

- (SomeStructType)myMeth:(SomeArgType)arg;

那么这实际上是一个普通的 C 函数:

SomeStructType myMeth(id self, SEL _cmd, SomeArgType arg);

我很确定您已经知道这一点,但我只是为其他读者提一下。换句话说,您想询问 libffi 或任何类型的类似库如何SomeStructType为该架构返回。

于 2013-12-01T23:03:22.477 回答
0

来自http://www.sealiesoftware.com/blog/archive/2008/10/30/objc_explain_objc_msgSend_stret.html

结构类型在寄存器中返回的规则总是晦涩难懂,有时甚至是疯狂的。ppc32 很简单:结构永远不会在寄存器中返回。i386 很简单:sizeof 正好等于 1、2、4 或 8 的结构体在寄存器中返回。x86_64 更复杂,包括在 FPU 寄存器中返回浮点结构字段的规则,而 ppc64 的规则和异常会让你头晕目眩。血淋淋的细节记录在 Mac OS X ABI 指南中,尽管像往常一样,如果文档和编译器不一致,那么文档就是错误的。

如果您直接调用 objc_msgSend 并且需要知道是否将 objc_msgSend_stret 用于特定的结构类型,我推荐经验方法:编写一行代码调用您的方法,在您关心的每个架构上编译它,然后查看汇编代码以查看编译器使用哪个调度函数。

于 2015-05-31T03:51:36.360 回答