Как может SEL, определенный для возврата идентификатора, представлять метод, который возвращает double? - PullRequest
2 голосов
/ 12 октября 2011

В Objective-C есть тип с именем SEL. Это определено так:

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

но если мы создадим метод с типом возвращаемого значения double, тип id не годится для использования.

Как может среда выполнения Objective C работать с этой проблемой?

1 Ответ

5 голосов
/ 12 октября 2011

SEL определяется как typedef struct objc_selector *SEL;, поэтому вы ошибаетесь.

SEL - это тип, используемый для хранения селектора, который в основном является «именем» метода, наряду с некоторой другой информацией.


Во всяком случае,

В случае double возвращаемого типа Objective-C просто возвратит double. Неважно, как объявлены SEL и id. (Точно так же как printf, но наоборот: возвращайте значение вместо аргументов функции.)

Реализация метода +[A a] в этом примере программы:

@interface A

+ (double)a;

@end

@implementation A

+ (double)a {
  return 1.0f;
}

@end

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

Дает вывод этой сборки (это функция с сгенерированным именем, которое вы не знаете: вы не можете просто вызвать его по имени *):

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:

Он просто возвращает double, даже если double требуется больше байтов, чем id. Между ними нет перевода на С, так что это не проблема. Обратите внимание, что возвращаемые значения методов Objective C не являются типобезопасными .

Основная функция вызывает _objc_msgSend (которая вызывает «безымянную» функцию, указанную IMP*) и помещает возвращаемое значение в b.


* адрес этой функции сохраняется в определении метода как переменная типа IMP. IMP равно определено id (*IMP)(id, SEL, ...).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...