Dans MyClass.m, j'ai défini
- (void) myTest: (NSString *) withAString{
NSLog(@"hi, %@", withAString);
}
et la déclaration appropriée dans MyClass.h. Plus tard, je veux appeler
[self performSelector:@selector(mytest:withAString:) withObject: mystring];
dans MyClass.m mais j'obtiens une erreur similaire à * Terminer l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '* - [MyClass myTest: withAtring:]: sélecteur non reconnu envoyé à l'instance 0xe421f0'
J'ai essayé un cas plus simple avec un sélecteur qui ne prenait aucun argument qui imprimait une chaîne sur la console et qui fonctionnait très bien. Quel est le problème avec le code et comment puis-je le résoudre? Merci.
Réponses:
La signature de votre méthode est:
withAString se trouve être le paramètre (le nom est trompeur, il semble qu'il fasse partie de la signature du sélecteur).
Si vous appelez la fonction de cette manière:
Ça va marcher.
Mais, comme l'ont suggéré les autres affiches, vous voudrez peut-être renommer la méthode:
Et appelez:
la source
En Objective-C, la signature d'un sélecteur se compose de:
Les sélecteurs n'ont aucune connaissance de:
Voici une implémentation de classe où la méthode performMethodsViaSelectors effectue les autres méthodes de classe au moyen de sélecteurs:
La méthode pour laquelle vous souhaitez créer un sélecteur a une seule entrée, vous devez donc créer un sélecteur pour elle comme suit:
la source
@Shane Arney
Vous voudrez peut-être également mentionner que cette méthode sert uniquement à transmettre un maximum de 2 arguments et qu'elle ne peut pas être retardée. (comme
performSelector:withObject:afterDelay:)
.un peu bizarre qu'Apple ne supporte que 2 objets à envoyer et ne le rend pas plus générique.
la source
Votre code a deux problèmes. L'un a été identifié et répondu, mais pas l'autre. La première était que votre sélecteur manquait le nom de son paramètre. Cependant, même lorsque vous corrigez cela, la ligne lèvera toujours une exception, en supposant que votre signature de méthode révisée inclut toujours plus d'un argument. Disons que votre méthode révisée est déclarée comme:
Créer des sélecteurs pour des méthodes qui acceptent plusieurs arguments est parfaitement valide (par exemple @selector (myTestWithString: compareTo :)). Cependant, la méthode performSelector ne vous permet de passer qu'une seule valeur à myTest, qui a malheureusement plus d'un paramètre. Cela provoquera une erreur et vous indiquera que vous n'avez pas fourni suffisamment de valeurs.
Vous pouvez toujours redéfinir votre méthode pour prendre une collection car ce n'est qu'un paramètre:
Cependant, il existe une solution plus élégante (qui ne nécessite pas de refactorisation). La réponse est d'utiliser NSInvocation, ainsi que ses méthodes
setArgument:atIndex:
etinvoke
.J'ai rédigé un article, y compris un exemple de code , si vous voulez plus de détails. L'accent est mis sur le filetage, mais les bases s'appliquent toujours.
Bonne chance!
la source
Votre signature de méthode n'a aucun sens, êtes-vous sûr que ce n'est pas une faute de frappe? Je ne sais pas comment il est même compilé, même si vous recevez peut-être des avertissements que vous ignorez?
Combien de paramètres pensez-vous que cette méthode prendra?
la source
Pensez que la classe devrait être définie comme:
Vous n'avez qu'un seul paramètre, vous ne devriez donc en avoir qu'un seul:
Vous pouvez également envisager d'utiliser% @ dans votre NSLog - c'est juste une bonne habitude à prendre - qui écrira alors n'importe quel objet - pas seulement des chaînes.
la source
Le document Apple indique qu'il n'y a pas d'API disponible pour cette fonctionnalité et une autre fonctionnalité attendue dans un clavier personnalisé. vous devez donc découvrir votre propre logique pour implémenter cela.
la source