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, ...)
.
精彩评论