NSLog dans dealloc pas executé ??

AliGatorAliGator Membre, Modérateur
22:58 modifié dans Vos applications #1
Bijour à  tous !

Je suis en train de développer une sous-classe de NSView qui a pour simple but de contenir une NSMatrix*
Le problème c'est que mon dealloc n'a pas l'air d'être appelé : en effet le NSLog que j'ai mis dedans n'est pas affiché... Comment se fait-ce ??!?

Ah j'en profite pour vous demander au passage : mon "_matrix = nil" est-il utile ? (dans "createNewMatrixWithRows:columns:" je release _matrix, pour que si j'appelle cette méthode plus tard dans mon code ça remplace la NSMatrix existante par la nouvelle ; d'où mon affectation à  nil avant le premier appel) Ou bien est-ce que toute variable déclarée dans le .h vaut nil au lancement de l'appli ??
- (id)initWithFrame:(NSRect)frameRect<br />{<br />	if ((self = [super initWithFrame:frameRect]) != nil) {<br />		// Add initialization code here<br />		_matrix = nil; // really useful ??<br />		[self createNewMatrixWithRows:3 columns:3];<br />		<br />		[self setAutoresizesSubviews:YES]; // will call resizeSubviewsWithOldSize when needed<br />	}<br />	<br />	return self;<br />}<br /><br />- (void)dealloc<br />{<br />	NSLog(@&quot;Ben merde pourquoi ce message s&#39;affiche pas ??&quot;);<br />	// don&#39;t forget to remove the matrixfrom the view !<br />	[_matrix removeFromSuperview];<br />	[_matrix release];<br />	[super dealloc];<br />}
"createNewMatrixWithRows:columns:" est une méthode de ma classe qui instancie une NSMatrix dans _matrix (après avoir détaché de la superView releasé une éventuelle ancienne)

Thanks !

*j'aurais pu sous-classer NSMatrix mais en fait je veux que ma NSMatrix soit contrainte à  être carrée et centrée, donc si ma NSView contenante est rectangulaire de taille W*H, ma NSMatrix prend comme taille MIN(W,H) pour chaque côté, et est centrée dans la NSView... je sais pas si c'est le mieux comme méthode mais bon, ça marche, alors... :P

Réponses

  • ChachaChacha Membre
    22:58 modifié #2
    Salut,

    dans 1124436830:

    Ah j'en profite pour vous demander au passage : mon "_matrix = nil" est-il utile (...) Ou bien est-ce que toute variable déclarée dans le .h vaut nil au lancement de l'appli ??

    Inutile, en effet : toutes les données d'instance d'un objet sont initialisées à  0.

    Après, si le dealloc ne s'exécute pas:
    -si c'est quand tu fermes l'appli, c'est presque normal : la mémoire est libérée d'un coup sans faire appel aux destructeurs en cascade pour les objets contenus dans les .nib
    -connais-tu la gestion de la mémoire en Objective-C ? Un objet compte les références des objets qui pointent dessus. Il n'est désalloué que si le nombre de références toombe à  0. Peut-être ta matrice est-elle encore retenue quelque part...
    exemple:
    <br />Toto* toto = [[Toto alloc] init]; //toto a un compteur de refs. à  1<br />Toto* titi = toto;//toto a toujours un compteur de refs. à  1<br />Toto* tutu = [toto retain];//toto a maintenant un compteur de refs. à  2<br />[toto release];//le compteur retombe à  1, pas à  0 : toto n&#39;est pas désalloué<br />[tutu release];//le compteur tombe à  0, là , toto est désalloué<br />
    


    +
    Chacha
  • AliGatorAliGator Membre, Modérateur
    22:58 modifié #3
    Merci de ta réponse si rapide :o
    dans 1124437987:

    Salut,

    Inutile, en effet : toutes les données d'instance d'un objet sont initialisées à  0.
    Ok c'est bien ce qu'il me semblait. Donc je peux sans risque supprimer cette ligne, si je fais un [_matrix release] dans "createNewMatrixWithRows:columns:" ça risquera pas d'envoyer le release à  un objet quelconque. Ouf.
    (j'avais un doute que _matrix, puisque pas encore initialisé à  ce stade, risquait de pointer n'importe où (comme un pointeur en C non initialisé), lui envoyer alors un retain aurait pu fouttre un gros boxon)

    dans 1124437987:
    Après, si le dealloc ne s'exécute pas:
    -si c'est quand tu fermes l'appli, c'est presque normal : la mémoire est libérée d'un coup sans faire appel aux destructeurs en cascade pour les objets contenus dans les .nib
    Heu ok, mais alors quand je quitte mon appli, ma NSView (enfin sous-classe de NSView en fait, crée par IB et pas par code) elle est bien détruite, non ? le dealloc de cette sous-classe ne serait alors pas appelé d'après ce que tu dis ?? Ca me parait bizarre, comment je fais pour releaser ma variable d'instance _matrix alors, que j'ai alloc/init dans le initWithFrame (enfin dans le createnewMatrixWithRows:columns: en fait) ??
    dans 1124437987:
    -connais-tu la gestion de la mémoire en Objective-C ? Un objet compte les références des objets qui pointent dessus. Il n'est désalloué que si le nombre de références toombe à  0. Peut-être ta matrice est-elle encore retenue quelque part...
    Ben oui je sais bien je connais le reference counting... D'ailleurs j'y ai fait gaffe dans mon createNewMatrixWithRows:columns: (je détache ma NSMatrix de ma NSView, puis lui envoie un release, avant d'en alloc/init une nouvelle et de la réattacher, puisque j'ai vu que addSubview: faisait un retain)

    Je vais vérifier que j'ai bien fait le bon nombre de release, ceci dit là  c'est le dealloc de ma classe perso de NSView, donc seul IB la crée, et elle devrait être donc dealloc quand l'appli quitte, non ?

    (Pour rappel : j'ai créé une sous-classe de NSView, squareBoard, et dans son initWithFrame elle crée par code une NSMatrix qu'elle rajoute à  ses subViews. j'ai mis un objet squareBoard dans mon interface avec IB, et je n'en crée pas d'autre par code. Donc je veux bien m'être gourré sur le nombre de alloc/init/release sur mes NSMatrix créées et rajoutées en subView par code, mais sur ma NSView normalement j'en crée aucune par code...)
  • ChachaChacha Membre
    22:58 modifié #4
    dans 1124437987:

    Donc je peux sans risque supprimer cette ligne, si je fais un [_matrix release] dans "createNewMatrixWithRows:columns:" ça risquera pas d'envoyer le release à  un objet quelconque.

    Et oui, parce qu'en plus, Objective-C autorise [nil release];


    Heu ok, mais alors quand je quitte mon appli, ma NSView (enfin sous-classe de NSView en fait, crée par IB et pas par code) elle est bien détruite, non ? le dealloc de cette sous-classe ne serait alors pas appelé d'après ce que tu dis ??

    Ben oui. Il y a des gens très intelligents que ça a déjà  surpris. Cf ici:
    http://www.objective-cocoa.org/forum/index.php?topic=733.msg8185#msg8185


    Ca me parait bizarre, comment je fais pour releaser ma variable d'instance _matrix alors, que j'ai alloc/init dans le initWithFrame (enfin dans le createnewMatrixWithRows:columns: en fait) ??

    Si t'avais pas re-répondu si rapidement, j'aurais pu corriger ma grosse faute : ce n'est pas _matrix, qui est retenue dans un coin, c'est ta nsview (c'est à  elle, le dealloc). Désolé.


    Je vais vérifier que j'ai bien fait le bon nombre de release, ceci dit là  c'est le dealloc de ma classe perso de NSView, donc seul IB la crée, et elle devrait être donc dealloc quand l'appli quitte, non ?

    Si c'est IB qui la crée, le dealloc, ne sera pas appelé, donc.

    +
    Chacha
  • AliGatorAliGator Membre, Modérateur
    août 2005 modifié #5
    dans 1124440042:

    Et oui, parce qu'en plus, Objective-C autorise [nil release];
    Ben je sais bien, c'est pour ça que je me suis pas embêté à  mettre un "if (_matrix)" dans mon createNewMatrixWithRows:columns: avant de faire mon [_matrix release]

    dans 1124440042:
    Ben oui. Il y a des gens très intelligents que ça a déjà  surpris. Cf ici:
    http://www.objective-cocoa.org/forum/index.php?topic=733.msg8185#msg8185
    Ah ok... ben mince alors, pour une fois que j'avais tout fait bien... (1) j'avais fait une recherche sur les forums avant de poster pourtant, mais j'avais pas trouvé ce thread :( (2) pour une fois que j'avait pensé à  bien faire mon release sur _matrix, à  implémenter mon dealloc, et à  bien appeler [super dealloc] dedans et tout, j'en étais fier... raté ! :)
    Enfin bon faut quand même le faire puisque si un jour j'utilise ma classe autre part et que je l'instancie par code, le dealloc servira. mais bon...

    Bon alors en gros, soit je m'en fout que _matrix soit pas releasé lors du pomme-Q puisque OSX va libérer toute la mémoire tout seul au moment de quitter ? ou alors je peux surcharger appWillTerminate, mais ça m'a pas l'air utile...

    dans 1124440042:
    Si t'avais pas re-répondu si rapidement, j'aurais pu corriger ma grosse faute : ce n'est pas _matrix, qui est retenue dans un coin, c'est ta nsview (c'est à  elle, le dealloc). Désolé.
    Ouaip. Je sais, c'est "confusant" :) mais c'est bien ça
Connectez-vous ou Inscrivez-vous pour répondre.