У меня есть метод класса, возвращающий 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_unretained 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);
Это объясняет мне ошибки компилятора, но что я использую на уровне времени выполнения, чтобы вызывать класс и его статический метод во время выполнения и возвращать значение структуры?