开发者

How can a SEL, defined to return id, represent a method that returns a double?

In Objective-C there is a type named SEL. It's defined like this:

id (*SEL)(id self, SEL _cmd,...);

but if we make a method whose return type i开发者_运维知识库s double, the id type is not good to use.

How can the Objective-C runtime work with this problem?


SEL is defined as typedef struct objc_selector *SEL;, so you are wrong.

SEL is a type used to store a selector, which basically is the "name" of a method, along with some other information.


Anyway,

In the case of a double return type, Objective-C will simply return a double. It doesn't care about how SEL and id are declared. (Just like printf but the other way around: return value instead of function arguments.)

The implementation of the +[A a] method in this sample program:

@interface A

+ (double)a;

@end

@implementation A

+ (double)a {
  return 1.0f;
}

@end

int main() {
  double b = [A a];
  return 0;
}

Gives this assembly output (which is a function with a generated name you don't know: you can't just call it by its name*):

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:

It just returns a double, even if a double needs more bytes than id. It isn't translated to C in between, so this is no problem. Note that the returned values of Objective-C methods are not type-safe.

The main function calls _objc_msgSend (which calls the "nameless" function pointed to by the IMP*) and puts the return value of it into b.


*the address of that function is stored in the method definition as a variable of type IMP. An IMP is defined id (*IMP)(id, SEL, ...).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜