Forcer un break sur selector not recognized
Salut,
J'ai un problème un peu compliqué. Dans un de mes programmes, quand je drag'n drop un truc, un "selector not recognized" apparaà®t dans la console. Effectivement, d'après le log, il semblerait que j'essaye de faire un objectAtIndex: sur un NSDictionary. Mais l'erreur est assez difficile à trouver : le programme ne plantant pas, je ne sais absolument pas où ce message est déclenché.
D'habitude, à coup de NSLog("toto"), j'arrive à voir d'où ça vient, mais là , nada ! La difficulté réside dans le fait qu'apparemment, ce message est déclenché dans une méthode de Cocoa, pas dans une des miennes. Effectivement il suffirait d'une petite erreur de mon modèle de données pour propager cette erreur très loin dans la boucle événementielle. Toujours parce que c'est dans un drag'n drop, je ne peux pas mettre le débuggueur en pause pendant l'événement déclencheur, puisque je suis déjà en train d'utiliser ma souris. J'ai mis des break points de partout, mais impossible de situer le problème.
Mon espoir résiderait dans le fait qu'on arrive à dire au programme qu'il doit planter sur une erreur de ce type, au lieu de continuer à fonctionner comme un crétin. Savez-vous comment faire ça ?
Et pourtant, j'ai eu beau activer un maximum de warnings, mon code a l'air correct...
Je suis un peu désespéré, là .
+
Chacha
[edit]
Une précision : le message d'erreur apparaà®t quelque part après un appel à
(que j'ai redéfinie)
Même avec une implémentation très minimaliste de cette méthode, le problème persiste:
Si je renvoie, NO, il n'y a pas de selector not recognized, mais c'est plutôt normal : dans ce cas le drag'n drop est annulé.
J'ai un problème un peu compliqué. Dans un de mes programmes, quand je drag'n drop un truc, un "selector not recognized" apparaà®t dans la console. Effectivement, d'après le log, il semblerait que j'essaye de faire un objectAtIndex: sur un NSDictionary. Mais l'erreur est assez difficile à trouver : le programme ne plantant pas, je ne sais absolument pas où ce message est déclenché.
D'habitude, à coup de NSLog("toto"), j'arrive à voir d'où ça vient, mais là , nada ! La difficulté réside dans le fait qu'apparemment, ce message est déclenché dans une méthode de Cocoa, pas dans une des miennes. Effectivement il suffirait d'une petite erreur de mon modèle de données pour propager cette erreur très loin dans la boucle événementielle. Toujours parce que c'est dans un drag'n drop, je ne peux pas mettre le débuggueur en pause pendant l'événement déclencheur, puisque je suis déjà en train d'utiliser ma souris. J'ai mis des break points de partout, mais impossible de situer le problème.
Mon espoir résiderait dans le fait qu'on arrive à dire au programme qu'il doit planter sur une erreur de ce type, au lieu de continuer à fonctionner comme un crétin. Savez-vous comment faire ça ?
Et pourtant, j'ai eu beau activer un maximum de warnings, mon code a l'air correct...
Je suis un peu désespéré, là .
+
Chacha
[edit]
Une précision : le message d'erreur apparaà®t quelque part après un appel à
<br />-(BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard<br />
(que j'ai redéfinie)
Même avec une implémentation très minimaliste de cette méthode, le problème persiste:
<br />-(BOOL)outlineView:(NSOutlineView *)outlineView writeItems:(NSArray *)items toPasteboard:(NSPasteboard *)pboard<br />{<br /> NSLog(@"toto");<br /> return YES; //le problème apparaà®t plus loin; en mode pas-à -pas du<br /> //débuggeur, ce sera au milieu d'un code assembleur<br />}<br />
Si je renvoie, NO, il n'y a pas de selector not recognized, mais c'est plutôt normal : dans ce cas le drag'n drop est annulé.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Cette méthode est appellée tout à la fin quand le runtime n'arrive pas à trouver une cible dans la hiérarchie des messages pour le sélecteur en cours d'invocation.
Dans l'implémentation, tu peux faire tout ce que tu veux, comme, notamment, lever tes propres exceptions, faire tes NSLog ou mettre des breakpoints.
Tu peux aussi jouer que la possibilté de "loguer" une exception en exécutant le code ci-dessous le plus tôt possible avant l'apparition d'une exception :
[tt][[NSExceptionHandler defaultExceptionHandler] setExceptionHandlingMask:767][/tt]
.
Yep, ce sont de bonnes idées (merci !). J'ai essayé, mais ça n'a pas marché. Ma surcharge de forwardInvocation: ne semble pas être prise en compte (jamais appelée), et le NSExceptionHandler ne me donne pas de renseignements très intéressants.
Pour le forwardInvocation:, voici un test tout bête : je fais ma catégorie, j'inclus le header dans un fichier quelconque, et dans une méthode quelconque de ce fichier, je fais [self pouf]; (pouf n'existant pas bien sûr). Et bien la forwardInvocation: n'est pas appelée.
Ce n'est pas trop grave que ça reste en suspens, parce que de toutes manières, grâce à toi Bru, j'ai révisé le forwardInvocation, appris des nouveaux trucs en l'utilisant, et découvert le framework NSExceptionHandling (même pas documenté, celui-là !).
Comme quoi, je fais bien d'exposer mes problèmes, même un peu foireux : on découvre toujours des trucs en cascade.
+
Un Chacha reconnaissant