dealloc non appelé

ChachaChacha Membre
20:29 modifié dans API AppKit #1
Salut,

Je ne sais pas quelle partie du forum était la plus adaptée pour ce thread, donc je l'ai mis dans Objective-C par défaut.

Voilà , j'ai constaté que dans certains cas, le destructeur dealloc peut ne pas être appelé. Je m'explique :

--- Description des symptômes ----
Considérons une appli multi-documents avec une fenêtre, et dans cette fenêtre un objet du genre NSButton, NSView, NSImageView... (j'en ai essayé plusieurs, ça n'a pas d'importance). Disons NSButton.

Je veux ajouter un comportement à  mon bouton, je crée donc une classe MyButton, que j'attribue à  mon NSButton, dans Interface Builder, par la magie de l'inspecteur "Custom class".

Comme le NSButton est déjà  instancié dans le .NIB, le constructeur "init" de mon objet ne sera jamais appelé. Je lui substitue donc une surcharge de "awakeFromNib" dans la classe MyButton pour faire mes petites initialisations.

Quand je démarre l'appli, ou que je crée un document dans l'appli (Pomme-N), le "awakeFromNib" est bien appelé à  chaque fois, c'est nickel.

Maintenant, je veux aussi faire du nettoyage quand l'objet disparaà®t, donc je surcharge le dealloc de ma classe MyButton. Si l'appli est démarrée, je peux créer un nouveau document (awakeFromNib est appelé) puis le fermer (Pomme-W); dans ce cas, dealloc est bien appelé, c'est formidable.

En revanche, si je quitte l'appli (Pomme-Q) alors qu'un document est ouvert, je constate que le dealloc n'est pas appelé.

Dans le cas d'une appli monodocument, c'est pareil : le awakefromnib est appelé au démarrage, mais le dealloc n'est pas appelé après le Pomme-Q.

--- Solution de secours ---
Une solution de secours que j'ai adoptée est de rendre ma classe sensible à  la notification "ApplicationWillTerminateNotification", et de m'arranger pour faire du nettoyage à  ce moment là .


---- Réflexions ----
Maintenant, plusieurs questions se posent à  moi.
1) Est-ce que c'est bien normal, que dealloc ne soit pas appelé quand l'appli quitte ? Parce que si je voulais vraiment qu'il soit appelé, je n'aurais qu'à  fermer le document (Pomme-W) avant de quitter (Pomme-Q), et ce serait bon.

2) Le fait que dealloc ne soit pas appelé en fin d'application ne semble pas trop grave, dans la mesure ou c'est le système qui va se charger de récupérer la mémoire allouée par l'application. Il n'y aura pas de fuite mémoire associée. Mais pour d'autres types de resources, comme des File Descriptor de bas niveau, est-ce que le système va être capable de les fermer automatiquement ?

3) Qu'en pensez-vous ?

+
Chacha

Réponses

  • cbrandtcbrandt Membre
    mars 2005 modifié #2
    dans 1110373597:

    1) Est-ce que c'est bien normal, que dealloc ne soit pas appelé quand l'appli quitte ? Parce que si je voulais vraiment qu'il soit appelé, je n'aurais qu'à  fermer le document (Pomme-W) avant de quitter (Pomme-Q), et ce serait bon.
    2) Le fait que dealloc ne soit pas appelé en fin d'application ne semble pas trop grave, dans la mesure ou c'est le système qui va se charger de récupérer la mémoire allouée par l'application. Il n'y aura pas de fuite mémoire associée.

    il me semble que apple l'a fait exprès, pour que les applis se ferment plus vite... vu que de toutes façons la mémoire occupée par l'appli va se libérer, comme tu le fais justement remarquer.

    dans 1110373597:

    Mais pour d'autres types de resources, comme des File Descriptor de bas niveau, est-ce que le système va être capable de les fermer automatiquement ?

    oui, sauf si indiqué explicitement dans la doc (j'ai vu quelques cas, mais je ne sais plus où)

    dans 1110373597:

    3) Qu'en pensez-vous ?

    ne pas trop se prendre la tête à  ce niveau, sauf si cas cité juste au dessus - dans ce cas le appWillTerminate est parfait.


    edit:
    je t'ai grillé, mpergand...  :P
  • mpergandmpergand Membre
    20:29 modifié #3

    Comme le NSButton est déjà  instancié dans le .NIB, le constructeur "init" de mon objet ne sera jamais appelé


    c'est initWithCoder  ;)


    En revanche, si je quitte l'appli (Pomme-Q) alors qu'un document est ouvert, je constate que le dealloc n'est pas appelé.


    c'est normal


    Le fait que dealloc ne soit pas appelé en fin d'application ne semble pas trop grave, dans la mesure ou c'est le système qui va se charger de récupérer la mémoire allouée par l'application. Il n'y aura pas de fuite mémoire associée. Mais pour d'autres types de resources, comme des File Descriptor de bas niveau, est-ce que le système va être capable de les fermer automatiquement ?


    Oui, tous les fichiers ouverts par le process seront fermés et bien d'autres choses, comme un canal bluetooth etc.

  • ChachaChacha Membre
    mars 2005 modifié #4
    dans 1110374364:


    Comme le NSButton est déjà  instancié dans le .NIB, le constructeur "init" de mon objet ne sera jamais appelé


    c'est initWithCoder  ;)

    Ah, oui, c'est vrai ! Sauf pour les CustomView (en fait on me l'a déjà  dit sur ce forum, j'avais oublié).


    Oui, tous les fichiers ouverts par le process seront fermés et bien d'autres choses, comme un canal bluetooth etc.

    C'est rassurant, mais je ne trouve pas ça bien propre.

    +
    Chacha

    PS: est-ce que c'est mal d'utiliser awakeFromNib à  la place de initWithCoder ? ça peut poser des problèmes ?
  • cbrandtcbrandt Membre
    20:29 modifié #5
    dans initWithCoder, tes outlet ne sont pas encore connectés...
    dans awakeFromNib ils le sont.
  • ChachaChacha Membre
    20:29 modifié #6
    dans 1110375962:

    dans initWithCoder, tes outlet ne sont pas encore connectés...
    dans awakeFromNib ils le sont.


    S'il n'y a que ça comme différence, ça me va. Et puis ça ne fait pas de mal de le rappeler de temps en temps.
    Merci!

    +
    Chacha
Connectez-vous ou Inscrivez-vous pour répondre.