40 votes

Valeur de retour pour performSelector :

Quelle sera la valeur de retour de performSelector : si je passe un sélecteur qui renvoie un type primitif (sur l'objet), comme 'week' sur NSDateComponents (qui renvoie un int) ?

84voto

dizy Points 3755

Un exemple d'utilisation de NSInvocation pour retourner un flottant :

SEL selector = NSSelectorFromString(@"someSelector");
if ([someInstance respondsToSelector:selector]) {
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:
                                [[someInstance class] instanceMethodSignatureForSelector:selector]];
    [invocation setSelector:selector];
    [invocation setTarget:someInstance];
    [invocation invoke];
    float returnValue;
    [invocation getReturnValue:&returnValue];
    NSLog(@"Returned %f", returnValue);
}

9voto

dasdom Points 6905

Je pense que vous ne pouvez pas obtenir la valeur de retour de performSelector. Vous devriez regarder dans NSInvocation .

6voto

dopcn Points 8

Nouvelle réponse à une vieille question.

Il existe un moyen plus concis d'obtenir la valeur de retour de la fonction performSelector

NSInvocationOperation *invo = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(height) object:nil];
[invo start];
CGFloat f = 0;
[invo.result getValue:&f];
NSLog(@"operation: %@", @(f));

dans laquelle

- (CGFloat)height {
    return 42;
}

sortie

2017-03-28 16:22:22.378 redpacket[46656:7361082] operation: 42

3voto

joshbodily Points 309

Pour répondre à la deuxième partie de la question, une autre façon d'invoquer un sélecteur qui renvoie une primitive serait d'obtenir un pointeur de fonction et de l'invoquer comme tel, comme dans (en supposant que someSelector renvoie un float et n'a pas d'arguments) ;

SEL selector = NSSelectorFromString(@"someSelector");
float (*func)(id,SEL) = (float (*)(id,SEL))[someInstance methodForSelector: selector];
printf("return value is: %f", (func)(someInstance, selector));

2voto

Anni S Points 531

J'ai essayé la NSInvocation implémentée comme suggéré par dizy, elle fonctionne comme prévu.

J'ai également essayé une autre méthode, à savoir

int result = objc_msgSend([someArray objectAtIndex:0], @selector(currentPoint));

dans le cas ci-dessus, nous contournons le compilateur et insérons l'appel objc_msgSend explicitement comme décrit dans le blog : http://www.cocoawithlove.com/2011/06/big-weakness-of-objective-c-weak-typing.html

Dans ce cas, j'ai reçu l'avertissement suivant : Déclaration implicite de la fonction de bibliothèque 'objc_msgSend' avec le type 'id (id, SEL, ...)'. ce qui est évident car nous appelons directement la fonction de bibliothèque.

J'ai donc mis en œuvre la NSInvocation qui fonctionne parfaitement bien pour moi.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X