У меня есть метод класса, возвращающий CGSize
, и я хотел бы вызвать его через функции времени выполнения Objective-C, потому что мне дан класс и имена методов в виде строковых значений.
Я компилирую с флагами ARC в XCode 4.2.
Сигнатура метода:
+(CGSize)contentSize:(NSString *)text;
Первое, что я попробовал, - это вызвать его с помощью objc_msgSend
следующим образом:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
id result = objc_msgSend(clazz, method, text);
Это привело к сбою с «EXC_BAD_ACCESS» и без трассировки стека. Я использовал его первым, потому что в документации для objc_msgSend
сказано:
Когда он встречает вызов метода, компилятор генерирует вызов одной из функций
objc_msgSend
,objc_msgSend_stret
,objc_msgSendSuper
илиobjc_msgSendSuper_stret
. [...] Методы, которые имеют структуры данных в качестве возвращаемых значений, отправляются с использованиемobjc_msgSendSuper_stret
иobjc_msgSend_stret
.
Затем я использовал objc_msgSend_stret
следующим образом:
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
Использование указанной выше сигнатуры дает мне следующие две ошибки компилятора и два предупреждения:
ошибка: Проблема автоматического подсчета ссылок: Неявное преобразование неявного -Objective-C указатель типа 'CGSize *' (он же 'struct CGSize *') на 'id' запрещен с предупреждением ARC
: семантическая проблема: несовместимые типы указателей, передающие 'CGSize *' (также известный как 'struct CGSize *') в параметр типа «id»
ошибка: автоматический подсчет ссылок. Проблема: неявное преобразование указателя Objective-C в «SEL» запрещено с предупреждением ARC
: семантическая проблема: передача несовместимых типов указателей «__unsafe_unrehibited Class» в параметр типа «SEL»
Если я посмотрю на объявление метода, это:
OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
, который идентичен objc_msgSend
:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
Это объясняет ошибки компилятора для меня, но что я использую на уровне времени выполнения для вызова класса и его статического метода во время выполнения и возврата значения структуры?