respondsToSelector: sent to deallocated instance : Les zombies suffisent pas !
Nebuchad34
Membre
Bonjour,
Je fait face à un problème assez curieux.
J'ai reproduit sur Mac OS X un clone de la classe UINavigationController. Son comportement est similaire à ce que l'on voit sur iPhone.
Les ViewControllers que je "push" sur mon navigation controller sont des NSViewController sousclassés contenant un navigationItem, toujours dans l'analogie avec le fonctionnement sous iPhone OS.
J'utilise ce système pour reproduire une navigation à la Front Row entre des viewControllers présentant des TableViews.
Je l'utilise depuis des mois sans soucis. Mais voilà , je rencontre un soucis inexplicable ! Tous tes mes sous-classe de PMViewController existantes peuvent être poussés sans soucis, mais si j'en crée une nouvelle et que je la "push", si je release mon navigation controller, j'ai un "respondsToSelector" envoyé à ce PMViewController alors qu'il a été releasé suite au release du navigationController. C'est d'autant plus curieux que je ne garde aucun pointeur dessus dans aucune de mes classes !
Ce que je voudrais, c'est savoir quelle instance de quelle classe envoi ce "respondsToSelector" à mon viewController releasé ? je ne le fait nulle part dans mes propres classes, c'est donc d'autant plus difficile à débugger.
Je fait face à un problème assez curieux.
J'ai reproduit sur Mac OS X un clone de la classe UINavigationController. Son comportement est similaire à ce que l'on voit sur iPhone.
Les ViewControllers que je "push" sur mon navigation controller sont des NSViewController sousclassés contenant un navigationItem, toujours dans l'analogie avec le fonctionnement sous iPhone OS.
J'utilise ce système pour reproduire une navigation à la Front Row entre des viewControllers présentant des TableViews.
Je l'utilise depuis des mois sans soucis. Mais voilà , je rencontre un soucis inexplicable ! Tous tes mes sous-classe de PMViewController existantes peuvent être poussés sans soucis, mais si j'en crée une nouvelle et que je la "push", si je release mon navigation controller, j'ai un "respondsToSelector" envoyé à ce PMViewController alors qu'il a été releasé suite au release du navigationController. C'est d'autant plus curieux que je ne garde aucun pointeur dessus dans aucune de mes classes !
Ce que je voudrais, c'est savoir quelle instance de quelle classe envoi ce "respondsToSelector" à mon viewController releasé ? je ne le fait nulle part dans mes propres classes, c'est donc d'autant plus difficile à débugger.
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
Dans la console tu dois pouvoir taper
po 0x54560d
Tu mets un breakpoint sur "-respondsToSelector:" et ce breakpoint devrait mettre en pause le programme à chaque fois que cette méthode est appellée, quel que soit l'endroit d'où c'est appelé.
2010-02-10 12:23:18.874 Poker Manager[8002:a0f] *** -[PMITunesMenuController respondsToSelector:]: message sent to deallocated instance 0xc8200b0
et si je fais :
(gdb) po 0xc8200b0
et bien il me reprint ça :
2010-02-10 12:23:30.751 Poker Manager[8002:a0f] *** -[PMITunesMenuController respondsToSelector:]: message sent to deallocated instance 0xc8200b0
Ali, comment je fait pour mettre un breakpoint sur methode ?
(Et puis si c'est plus ça la syntaxe, au pire ça doit bien être marqué dans l'aide ou via une recherche "breakpoints site:developper.apple.com" via Google :P)
Bien évidemment, la première chose à faire est une analyse statique de ton code ("Build & Analyze" dans le menu "Build", ou Pomme-Maj-A) pour essayer de détecter les erreurs de gestion mémoire que tu aurais laissé passer (l'analyse statique ne trouve pas forcément toutes les fuites mémoires, mais celles qu'elle trouve sont en général réelles, donc faut de toute façon au moins les corriger avant d'aller plus loin !)
Mettre un breakpoint sur respondsToSelector c'est ingérable. Il arrête sans arrêt.
Ben oui mais et alors ? personnalise un peu, ne demande qu'à s'arrêter qu'au bout d'un certain nombre de hits seulement (avec un peu de dichotomie tu devrais trouver un ordre de grandeur du nombre de hits du breakpoint au bout duquel il plante), ou tu mets des conditions sur tes breakpoints...
Sinon, puisque tu sembles dire que ça n'arrive qu'aux instances que tu crées par le code (via alloc/init dans ton code j'imagine), tu peux récupérer l'adresse mémoire de l'instance créée, et ne mettre ton breakpoint que sur cette instance-là (voire un inspecteur (watch variable) pour être informé quand la valeur à cette adresse mémoire change...
Et puis sinon puisque tu n'as ce cas que pour ces instances particulières là encore, tu peux ne mettre tes breakpoints (sur -respondsToSelector: comme sur tes adresses mémoires, etc) qu'après avoir envoyé le release.
Tu es sûr que tu n'as pas une méthode qui te retourne un objet autoreleasé... et que tu envoies un release supplémentaire sur cet objet ?
Quelle est la tête de la callstack quand ça plante à cet endroit ?
#0 0x96e8bab7 in ___forwarding___
#1 0x96e8b982 in __forwarding_prep_0___
#2 0x97cc04e7 in +[NSTextInputContext currentInputContext]
#3 0x97cc00ab in -[NSApplication updateWindows]
#4 0x97cbffd2 in _handleWindowsNeedUpdateNote
#5 0x96e91892 in __CFRunLoopDoObservers
#6 0x96e4e18d in __CFRunLoopRun
#7 0x96e4d864 in CFRunLoopRunSpecific
#8 0x96e4d691 in CFRunLoopRunInMode
#9 0x90a7bf0c in RunCurrentEventLoopInMode
#10 0x90a7bbff in ReceiveNextEventCommon
#11 0x90a7bb48 in BlockUntilNextEventMatchingListInMode
#12 0x97cbeac5 in _DPSNextEvent
#13 0x97cbe306 in -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:]
#14 0x97c8049f in -[NSApplication run]
#15 0x97c78535 in NSApplicationMain
#16 0x00008fe7 in main at main.m:13
Et non, pas d'objet autoreleasé. C'est vraiment très bizarre.
Je pousse plein de vues controlleur qui sont des sous classes de mon PMViewController et j'ai pas de pb.
Si j'en fait une nouvelle sur le même modèle que les précédentes, ça merdouille !
Ce qui ets bizarre c'Est que ça ne plante pas quand je pop le view controller, mais quand je release directement mon navigation controller après l'avoir retiré de la vue de ma fenêtre.
Si je pop mon view controlelr pour revenir à ma first view et que je vire mon navigation controller là ça ne plante plus !
http://www.cocoatreeapplications.com/_videos/bugRespondsToSelector.m4v
Vous allez comprendre pourquoi je vous dit que c'est très bizarre .
Cela fait deux jours que je bute là dessus, j'en ai maaaaaaaarrre
Et affiche la callstack (je suis pas habitué à ce layout de Xcode, je préfère le "All-In-One" où, quand tu débug, tu as tout sous les yeux, callstack, variables, console, breakpoints, ... là dans ta vidéo tu as juste la console c'est pas très parlant pour déboguer)