Gestion du pointeur sur un object désalloué

17:10 modifié dans API AppKit #1
Hello :)

Pourquoi lorsque après un certains nombre de release, une fois que l'object vient d'être désaoullé son pointeur ne revient pas à  nil "automatiquement" ?

Comment tester autre qu'avec un retainCount si une variable est toujours allouée, est ce peut être que si on le fait c'est qu'il y a une mauvaise gestion de la mémoire ? Mais qui n'a jamais fait un if (pointeurObject)... ?

le if (pointeurObject)... ne passe pas quand c'est nil, mais au début je pensais tester l'object la validité de l'object de cette façon mais en fait suis obligé de mettre le release en catégorie, de tester son retaincount et de mettre le pointeur à  nil si à  0 ?

Bon code à  vous,
Michaël.

Réponses

  • MalaMala Membre, Modérateur
    17:10 modifié #2
    Bonjour,

    il faut bien comprendre qu'un pointeur ne fait que "regarder" à  une adresse. Même si un objet est libéré, le pointeur regarde toujours le même endroit de la mémoire (aussi erronée soit-elle). Il n'est absolument pas dépendant de la classe qu'il pointe (on peut d'ailleurs à  tout moment lui demander de "regarder ailleurs").

    Il est donc important de bien maà®triser ses objets et donc les pointeurs qui nous permettent d'y accéder. Et d'après ce que je peux lire cela n'a pas l'air d'être le cas.

    Pour t'aider a y voir plus claire sur la gestion mémoire en Obj-C, je te conseilles la lecture suivante...
    http://www.projectomega.org/article.php?lg=fr&php=tuts_objc2&p=1

    if (pointeurObject)

    Cette façon de faire est excellente si l'on considère que l'objet que l'on test n'est pas en "autorelease". Je pense que ton problème vient de là . Tu ne maitrises pas la vie de l'objet que tu manipules.

    ...en fait suis obligé de mettre le release en catégorie, de tester son retaincount et de mettre le pointeur à  nil si à  0 ?

    Cela me semble bien compliqué. Deplus, comment vas tu mettre le pointeur à  nil??? N'oublies pas que dans ton release( que ce soit par catégorie ou par surcharge) tu n'accèdes a rien d'autre qu'aux données de ta classe mais en aucun cas à  un pointeur situé à  l'extérieur et qui pointerait sur ta classe. Est-ce que tu me suis? :-\

    En prenant le temps de lire la doc ci-dessus, je suis sûr que tu trouveras une solution bien plus simple à  ton problème. ;)

    Bonne continuation
  • 17:10 modifié #3
    Bonjour,
    Ce n'est pas du à  un problème particulier sur la gestion de la mémoire, j'essaye d'éviter au maximum l'autoreleasepool, mais dans certains car, par exemple avec une variable globale, il est assez pratique de mettre le pointeur à  nil au démarrage et de le remettre également à  nil après "certaines opérations terminées". Ce qui fait deux endroit où on le refait pointeur sur nil... je me demande simplement pourquoi il ne l'était pas mit automatiquement puisque par sécurité, mais juste pas sécurité je fais un if (pointeurObjet) afin d'être "sûr" que le programme ne va pas planter mais en fait si la variable à  été désallouée (normalement impossible puisque c'est moi qui la gère à  la "main") le programme foire.
    Mais j'ai l'impression que je me fais un match seul pour par grand chose....  :-\

    C'est vrai que mon "idée" est plutôt tordue, mais j'aime bien les idées tordues :p J'ai essayé :

    @implementation NSObject (MPCocoaExtensions)
    - (void)releaseAndNil
    {
    int i=[self retainCount];
    [self release];
    if (i==1)
    {
    NSLog(@self a nil);
    self=nil;
    }
    }
    @end


    et

    NSString *s=[[NSString alloc] initWithString:@abcd];
    NSLog(@s: %d,s);
    [s releaseAndNil];
    //s=nil;
    NSLog(@s: %d,s);

    Bon, ok m'arrête  :-X
  • BruBru Membre
    17:10 modifié #4
    Tu te poses un faux problème...

    Un objet n'a pas connaissance de la (ou des) variable qui stocke son pointeur. Dans ce cas, comment veux tu que le système puisse mettre la valeur nil dans cette (ou ces) variable ?

    Tu n'as normalement pas à  te soucier des problèmes de mémoire.
    Si tu as besoin d'un objet temporaire, alors utilise l'autorelease pool. Dans ce cas, généralement, le pointeur est dans une variable locale qui sera de toute façon détruite à  la sortie de la procédure/méthode.
    Si tu as besoin d'un objet que tu veux garder longtemps, alors utilise retain (ou créé l'objet par alloc/init), puis tu fais un release dès que tu en a plus besoin. Dans ce cas, le pointeur est généralement stocké dans une globale (ou dans une variable de classe par exemple).

    .
  • MalaMala Membre, Modérateur
    17:10 modifié #5
    Effectivement, tu aimes chercher des complications là  où il n'y en a pas en fait. ;)

    ...avec une variable globale...

    Pas bien ça!  ;D

    Si tu gères toi même ton objet alors tu sais qu'il n'est pas utilisé par une autre classe...

    Donc quand tu fais ton "Release", mets ton pointeur à  nil et voilà .

    Pour le reste, je ne dirais pas mieux que Bru donc... :-X

    le meilleur code est toujours le plus simple.

    Donc simplifions, simplifions, simplifions...   ;D ;D  ;D
  • BruBru Membre
    17:10 modifié #6
    dans 1092826831:

    ...avec une variable globale...

    Pas bien ça!  ;D


    Euh, en quoi c'est "pas bien" ? Même cocoa utilise des globales... A ton avis, c'est quoi NSApp ?

    .
  • nucleusnucleus Membre
    17:10 modifié #7
    dans 1092828132:

    dans 1092826831:

    ...avec une variable globale...

    Pas bien ça!  ;D


    Euh, en quoi c'est "pas bien" ? Même cocoa utilise des globales... A ton avis, c'est quoi NSApp ?


    Sauf si une seule et une seule instance d'un objet est strictement nécessaire (Singleton), utiliser des variables globales c'est, à  mon avis, chercher les histoires..

    Ca complique les tests unitaires, empèche l'utilisation de bouchons (Mock objects), limite la réutilisation, l'évolutabilité, etc..
    Bref ca limite les avantages que l'on peut avoir en faisant de l'objet..
  • 17:10 modifié #8
    dans 1092786293:

    if (pointeurObject)

    Cette façon de faire est excellente si l'on considère que l'objet que l'on test n'est pas en "autorelease". Je pense que ton problème vient de là . Tu ne maitrises pas la vie de l'objet que tu manipules.

    Mais le if (pointeurObject) équivaut à  if (pointeur>0) donc différent de nil, donc à  un moment on est obligé de le faire pointer vers nil ? Or par défaut un pointeur NSString *s; pointeur vers où bon luis semble, on peut met NSString *s=nil; ( mais if (pointeurObject) ne sert alors que dans peu de cas ou du moins à  aucun moment pour tester, pour asssuer que la méthode envoyé à  l'object ne crashera pas le programme... Un c'est bien ça  ? Dites moi si ce ne l'est pas :D
    Je me répond à  mon même en fait, depuis le début je l'utilise pour tester mes variables allouées par moi même alors que ça ne sert à  rien... puisque je viens de me rendre compte qu'une désallocation ne mettais pas à  nil le pointeur :-*
    Désolé pour le dérangement :D
  • MalaMala Membre, Modérateur
    17:10 modifié #9
    Ca complique les tests unitaires, empèche l'utilisation de bouchons (Mock objects), limite la réutilisation, l'évolutabilité, etc..
    Bref ca limite les avantages que l'on peut avoir en faisant de l'objet..

    Tu m'ôtes les mots de la bouche, merci ;D
Connectez-vous ou Inscrivez-vous pour répondre.