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) ?
Réponses
Trop de publicités?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);
}
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
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));
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.