Pergunta

Eu sei como criar um SEL em tempo de compilação usando @selector(MyMethodName:) mas o que eu quero fazer é criar um seletor de forma dinâmica a partir de um NSString. Isto é mesmo possível?

O que posso fazer:

SEL selector = @selector(doWork:);
[myobj respondsToSelector:selector];

O que eu quero fazer: (código pseudo, isso, obviamente, não funciona)

SEL selector = selectorFromString(@"doWork");
[myobj respondsToSelector:selector];

Eu tenho procurado a documentação da API da Apple, mas não encontrei uma maneira que não contam com a sintaxe em tempo de compilação @selector(myTarget:).

Foi útil?

Solução

Eu não sou um programador Objective-C, apenas um simpatizante, mas talvez NSSelectorFromString é o que você precisa. É explicitamente mencionado na Runtime Referência que você pode usar -lo para converter uma string para um seletor.

Outras dicas

De acordo com a documentação XCode, o seu psuedocode basicamente acerta.

É mais eficiente para valores atribuir a variáveis ??SEL em tempo de compilação com a directiva @selector (). No entanto, em alguns casos, um programa pode precisar converter uma cadeia de caracteres de um seletor em tempo de execução. Isso pode ser feito com a função NSSelectorFromString:

setWidthHeight = NSSelectorFromString(aBuffer);

Edit: Bummer, muito lento. : P

Eu teria que dizer que é um pouco mais complicado do que respostas dos entrevistados anteriores pode sugerir ... se você de fato quer realmente criar um selector . .. não apenas "chamada de um" que "tem que volta" ...

Você precisa criar um ponteiro de função que será chamado pelo seu método "novo" .. assim para um método como [self theMethod:(id)methodArg];, você escreveria ...

void (^impBlock)(id,id) = ^(id _self, id methodArg) { 
     [_self doSomethingWith:methodArg]; 
};

e então você precisa para gerar o bloco IMP dinamicamente, desta vez, de passagem, "eu", o SEL, e quaisquer argumentos ...

void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock);

e adicioná-lo à sua classe, juntamente com uma assinatura preciso método para todo o otário (neste caso "v@:@", de retorno vazio, objeto chamador, o argumento de objeto)

 class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "v@:@");

Você pode ver alguns bons exemplos deste tipo de runtime travessuras , em um dos meus repos, aqui.

Eu sei que este foi respondida por há muito tempo, mas ainda assim eu quero compartilhar. Isso pode ser feito usando sel_registerName também.

O código de exemplo a questão pode ser reescrita assim:

SEL selector = sel_registerName("doWork:");
[myobj respondsToSelector:selector];
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top