¿Cómo devuelvo un valor de estructura de un método de clase definido en tiempo de ejecución en ARC?
Tengo un método de clase que devuelve unCGSize
y me gustaría llamarlo a través de las funciones de tiempo de ejecución de Objective-C porque me dan los nombres de clase y método como valores de cadena.
Estoy compilando con indicadores ARC en XCode 4.2.
Firma del método:
+(CGSize)contentSize:(NSString *)text;
Lo primero que intenté fue invocarlo conobjc_msgSend
Me gusta esto
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
id result = objc_msgSend(clazz, method, text);
Esto se bloqueó con "EXC_BAD_ACCESS" y sin un seguimiento de la pila. Usé esto primero porque la documentación paraobjc_msgSend
dice
Cuando encuentra una llamada al método, el compilador genera una llamada a una de las funcionesobjc_msgSend
, objc_msgSend_stret
, objc_msgSendSuper
oobjc_msgSendSuper_stret
. [...] Los métodos que tienen estructuras de datos como valores de retorno se envían utilizandoobjc_msgSendSuper_stret
yobjc_msgSend_stret
.
Next, uséobjc_msgSend_stret
Me gusta esto
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
El uso de la firma anterior me da los siguientes dos errores del compilador y dos advertencias:
error: Problema de recuento de referencia automática: la conversión implícita de un puntero no Objective-C tipo 'CGSize *' (también conocido como 'struct CGSize *') a 'id' no está permitida con ARC
warning: Problema semántico: tipos de puntero incompatibles que pasan 'CGSize *' (también conocido como 'struct CGSize *') al parámetro del tipo 'id'
error: Problema de recuento de referencia automática: la conversión implícita de un puntero Objective-C a 'SEL' no está permitida con ARC
warning: Problema semántico: tipos de puntero incompatibles que pasan '__unsafe_unretained Class' al parámetro del tipo 'SEL'
Si miro la declaración del método, es:
OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
que es idéntico aobjc_msgSend
:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
Esto me explica los errores del compilador, pero ¿qué uso en el nivel de tiempo de ejecución para invocar una clase y su método estático en tiempo de ejecución y devolver un valor de estructura?