Bug avec contextual menu et vue perso, App plante -> Debuggeur -> EXC_BAD_ACCES
elf
Membre
Bonjour,
Pour le mode editeur de mon petit jeu j'ai utilisé un menu contextuel pour choisire le type de "tuile" à insérer.
Comme le mode editeur est asser similaire au mode jeu j'ai utilisé la même custom view. Ce menu est créer par code est ne contiens que des images 34x34 px. Quand j'utilise pour la première fois ce menu tout marche bien, mais des que j'édite une tuile, si j'essaye de faire réapparaitre le menu, l'application plante et retourne un code EXC_BAD_ACCES.
J'ai passé une journée entière à essayer de trouver d'où venais ce bug, et après des tonnes de tests, j'ai trouvé que si je suprimmer les images dans le menu tout fonctionnais bien.
Quelqu'un aurrais une idée d'où ce bug viens? Car je tiens à mes images!!!
elf
Pour le mode editeur de mon petit jeu j'ai utilisé un menu contextuel pour choisire le type de "tuile" à insérer.
Comme le mode editeur est asser similaire au mode jeu j'ai utilisé la même custom view. Ce menu est créer par code est ne contiens que des images 34x34 px. Quand j'utilise pour la première fois ce menu tout marche bien, mais des que j'édite une tuile, si j'essaye de faire réapparaitre le menu, l'application plante et retourne un code EXC_BAD_ACCES.
J'ai passé une journée entière à essayer de trouver d'où venais ce bug, et après des tonnes de tests, j'ai trouvé que si je suprimmer les images dans le menu tout fonctionnais bien.
Quelqu'un aurrais une idée d'où ce bug viens? Car je tiens à mes images!!!
elf
Connectez-vous ou Inscrivez-vous pour répondre.
Réponses
EXC_BAD_ACCESS est souvent dû à release de trop sur un objet.
Le bug, il vient certainement de ton application !
Mais sans code, sans rien, tu n'auras rien !
.
Le retain est inutile car une image importée dans ton projet (dans les ressources) est instanciée au lancement de ton appli et releasé à la fin de ton appli.
Donc je virerai les retain...
Hope this help...
Sauf que généralement, on évite d'utiliser allocWithZone: (un alloc seul suffit pour NSMenu et NSMenuItem).
De plus, le retain sur les images est inutile (mais pas pour les mêmes raisons que celles du Chat Noir), car le fait de faire unset: fait un retain implicte.
L'erreur peut venir d'autre part, et par coà¯ncidence, semble apparaitre dans ce code.
Tu peux éventuellement utiliser les zombies pour détecter les retains surnuméraires... Mais le mieux est de récupérer le crash-report de l'appli quand elle plante et de nous le montrer.
.
Voilà le crash report. Je ne vois pas trop en quoi ça pourrais aider mais bon, chui po un pro non plus! :fouf):
Pour éliminer d'autres pistes, peux tu faire ceci :
remplacer les [NSImage imageNamed:@...] par l'équivalent :
Ce test va permettre de mieux cerner l'origine du bug.
.
Je ne comprens toujours pas pourquoi ça fesais cela, et je ne vois qu'une réponse possible.
Entre ces deux codes il y a une subtile différence:
Le premier: l'image est autoreleasée alors que avec ton code elle l'est manuellement!
C'est probablement de la que ça viens...
En tout cas merci beaucoups!
Seulement, les bugs d'autorelease ont la faculté de très facilement se cacher. Le simple fait d'utiliser moins l'autorelease pool dans la seconde solution peut masquer le problème, qui risque de réapparaà®tre plus tard!
J'ai typiquement ce genre de réaction lorsque je fais un release sur un objet déjà autoreleasé.
Le problème étant que le plantage dans ce cas se fait bien après l'erreur, et pas dans le code correspondant >:(
La solution que j'ai donné à Elf était d'éviter l'utilisation de l'autorelasePool...
Il appert apparemment que le problème est à ce niveau.
Et pourquoi le suppute-je ?
C'est l'énoncé de Elf qui m'a intrigué :
Quelque chose qui marche 1 fois, mais qui peu de temps après ne marche plus, et génère une erreur mémoire... Ca pue typiquement l'objet qui a été désalloué entre temps !
Or qu'est ce qui est susceptible de désallouer un objet "un peu plus tard" si ce n'est l'autorelasePool...
Maintenant, je n'ai pas réussi à reproduire ce "bug".
Un menu créé dans un awakeFromNib, qui utilise des images chargées par imageNamed:, et qui est ensuite attaché à un NSView via setMenu: ne provoque aucun plantage chez moi.
D'une part, nous n'avons pas la partie de code intéressante (celle qui permet d'attacher le menu crée à la vue, ou celle qui appelle le menu), ensuite, il faudrait connaitre la version de l'AppKit qu'il utilise, etc...
.
Comme tu le dis depuis le début, ça sent l'autorelease!
Dans ce cas-là , personnellement, je relis les sources en recherchant et vérifiant:
- les créations d'objets
- les retain
- les release et autorelease
En général, je trouve pas mal de petits problème en regardant de plus près..., surtout des objets qui ne seraient jamais désalloués
Mais, bon, c'est aussi parce que je suis bien trop laxiste :brule: