Como retornar um valor struct de um método de classe definido em tempo de execução no AR
Tenho um método de classe retornando umCGSize
e eu gostaria de chamá-lo através das funções de tempo de execução Objective-C porque recebi os nomes de classe e método como valores de sequênci
Estou compilando com sinalizadores ARC no XCode 4.
ssinatura @Method:
+(CGSize)contentSize:(NSString *)text;
A primeira coisa que tentei foi invocá-lo comobjc_msgSend
como isso
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
id result = objc_msgSend(clazz, method, text);
This caiu com "EXC_BAD_ACCESS" e sem um rastreamento de pilha. Eu usei isso primeiro porque a documentação paraobjc_msgSend
diz,
Quando encontra uma chamada de método, o compilador gera uma chamada para uma das funçõesobjc_msgSend
, objc_msgSend_stret
, objc_msgSendSuper
ouobjc_msgSendSuper_stret
. [...] Métodos que possuem estruturas de dados como valores de retorno são enviados usandoobjc_msgSendSuper_stret
eobjc_msgSend_stret
.
Próximo, eu useiobjc_msgSend_stret
como isso
Class clazz = NSClassFromString(@"someClassName);
SEL method = NSSelectorFromString(@"contentSize:");
CGSize size = CGSizeMake(0, 0);
objc_msgSend_stret(&size, clazz, method, text);
Usando a assinatura acima, são apresentados os seguintes dois erros do compilador e dois avisos:
error: Problema na contagem automática de referências: A conversão implícita de um tipo de ponteiro não Objective-C 'CGSize *' (também conhecido como 'struct CGSize *') em 'id' é desabilitada com ARC
warning: Semântica: Tipos de ponteiros incompatíveis que passam 'CGSize *' (também conhecido como 'struct CGSize *') para o parâmetro do tipo 'id'
error: Problema na contagem automática de referências: A conversão implícita de um ponteiro Objective-C em 'SEL' não é permitida com ARC
warning: Problema semântico: Tipos de ponteiros incompatíveis passando '__unsafe_unretained Class' para o parâmetro do tipo 'SEL'
Se eu olhar para a declaração do método, é:
OBJC_EXPORT void objc_msgSend_stret(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
que é idêntico aobjc_msgSend
:
OBJC_EXPORT id objc_msgSend(id self, SEL op, ...)
__OSX_AVAILABLE_STARTING(__MAC_10_0, __IPHONE_2_0);
sso explica os erros do compilador, mas o que eu uso no nível do tempo de execução para chamar uma classe e seu método estático no tempo de execução e retornar um valor struc