J'adore coder sur le SDK de l'iPhone. C'est le codage le plus joyeux que j'ai fait depuis un quart de siècle (haletant!) Que j'ai passé à coder divers systèmes informatiques. C'est une combinaison d'Objective-C (élégant) et de cacao (magnifique). Il y a une exception que je continue à avoir et juste assez rarement pour que j'oublie pourquoi je l'obtiens. Je pensais que quelqu'un pourrait en tirer profit car c'est un piège facile à tomber.
L'exception en question:
*** Terminaison de l'application en raison d'une exception non interceptée 'NSInvalidArgumentException', raison: '*** - [UINavigationController pushViewController:]: sélecteur non reconnu envoyé à l'instance 0x5255c0'
Si vous utilisez le modèle d'application basée sur la navigation lors de la création d'un nouveau projet, vous obtiendrez un ensemble de fichiers de projet qui vous guidera dans la création d'une application fonctionnelle. En fait, vous pouvez appuyer sur build and go et l'application compilera, exécutera et vous montrera une jolie vue sous forme de tableau. Vous ajouterez probablement du code pour que la vue sous forme de tableau affiche des éléments dans les cellules, tout en effectuant des tests, et tout fonctionnera. À un moment donné, vous souhaiterez peut-être toucher aux cellules pour ouvrir une nouvelle vue. Le modèle fournit un exemple de méthode “didSelectRowAtIndexPath” illustrée ici:
- (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
// La logique de navigation peut aller ici. Créez et poussez un autre contrôleur de vue.
// AnotherViewController * anotherViewController = [[AnotherViewController alloc] initWithNibName: @ "AnotherView" bundle: nil];
// [self.navigationController pushViewController: anotherViewController];
// [publication de anotherViewController];
}
La méthode elle-même n'est pas commentée, mais toutes les instructions qu'elle contient sont. Ces lignes commentées fournissent un indice sur ce qui devrait se passer. La ligne
[self.navigationController pushViewController: anotherViewController];
est la clé du fonctionnement de cette méthode et de la cause de l’erreur. Il pousse un nouveau contrôleur de vue sur la pile de navigation et l'affiche, exactement comme vous le souhaitez. Cependant, si vous supprimez la mise en commentaire de cette ligne et l'ajustez pour utiliser le nouveau contrôleur de vue que vous avez créé, vous recevrez un avertissement lorsque vous la construirez: , c’est un avertissement, pas une erreur. Peuh. Exécutez-le, cependant, et vous obtiendrez l'erreur ci-dessus et un sélecteur non reconnu envoyé à une instance.
Si ce que vous avez lu jusqu'ici vous semble familier, la solution probable est simple. La ligne ci-dessus du modèle fourni par Apple est incorrecte. Il n'y a pas réellement de signature de message pour UINaigationController appelée -pushViewController: mais il en existe une appelée -pushViewController: animée: - Oups! Désolé Apple! Nous t'aimons toujours. Très facile à corriger, mais si cela se produit après une longue journée de codage, cela peut causer une frustration excessive. La ligne corrigée devrait ressembler à quelque chose comme:
[self.navigationController pushViewController: anotherViewController animé: YES];
Reconstruisez et cette erreur sera résolue! Si c'était ton problème. Si ce n'était pas le cas, alors ne désespérez pas. Le décryptage des messages d'exception fait partie de la partie amusante du style de vie de coderdom. Un «sélecteur non reconnu» continuera à faire référence au message que vous envoyez «à instance», un objet que vous avez créé. L'exception nous indique même quelle classe de l'objet reçoit le message étrange (UINavigationController dans ce cas) et le message qui a été envoyé (pushViewController :). Dans ce cas, le compilateur savait que le message envoyé avait quelque chose de piquant, mais il peut ne pas toujours être en mesure de le déterminer, vous ne pouvez donc pas vous en fier. Cependant, vous devriez pouvoir rechercher dans votre code le message signalé dans l'exception du journal de la console. Assurez-vous que tout est correct dans cette ligne en vérifiant dans la documentation la nature exacte de l'appel.