定义为返回id的SEL如何表示返回double的方法?

Lua*_*ang 2 types objective-c return-type selector

在Objective-C中有一个名为的类型SEL.它的定义如下:

id (*SEL)(id self, SEL _cmd,...);
Run Code Online (Sandbox Code Playgroud)

但是如果我们创建一个返回类型为的方法,则doubleid类型不适合使用.

Objective-C运行时如何解决这个问题?

小智 5

SEL被定义为typedef struct objc_selector *SEL;,所以你错了.

SEL 是一种用于存储选择器的类型,它基本上是方法的"名称",以及一些其他信息.


无论如何,

double返回类型的情况下,Objective-C将只返回一个double.它并不怎么关心SELid声明.(就像printf反过来一样:返回值而不是函数参数.)

+[A a]此示例程序中方法的实现:

@interface A

+ (double)a;

@end

@implementation A

+ (double)a {
  return 1.0f;
}

@end

int main() {
  double b = [A a];
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

给出这个程序集输出(这是一个你不知道的生成名称的函数:你不能只用名字*来调用它):

Leh_func_begin0:
## BB#0:
    pushq   %rbp
Ltmp0:
    movq    %rsp, %rbp
Ltmp1:
    movabsq $1, %rax  ; <-- moves 1.0f into the register
    cvtsi2sdq %rax, %xmm0 ; <-- converts quadword integer to double precision
    movq %rdi, -8(%rbp)
    movq %rsi, -16(%rbp)
    popq %rbp
    ret ; <-- returns control
    ; afterwards, the _main function gets the return value from the register
Leh_func_end0:
Run Code Online (Sandbox Code Playgroud)

它只返回一个double,即使double需要更多的字节id.它不会在中间转换为C,所以这没有问题.请注意,Objective-C方法的返回值不是类型安全的.

main函数调用_objc_msgSend(调用IMP*指向的"无名"函数)并将其返回值放入b.


*该函数的地址作为类型变量存储在方法定义中IMP.一个IMP 定义id (*IMP)(id, SEL, ...).