Allocation ivar dans un initWithNibName

AdauAdau Membre
00:01 modifié dans API AppKit #1
Coucou !

J'ai un code qui marche très bien, et qui à  priori ne provoque aucune fuite mémoire. Mais je vous explique:
J'ai une classe qui dérive de UITableViewController qui possède, pour des raisons de performances, une ivar NSArray (le contenu du tableau à  afficher).

Lors de l'initialisation de cette classe, il faut bien allouer un espace pour ce NSArray. Je le fais dans le initWithNibName puisque ce controlleur est appelé par cette fonction.
Je désalloue ce NSArray dans la commande dealloc de la classe.

Dans Instruments, il ne semble y avoir aucune fuite, mais avec une analyse de Clang, il me dit que l'objet n'est pas désalloué.

Il semblerait que mon code ne soit pas "légal".
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {<br />&nbsp; &nbsp; if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {<br />		[self setTitle:@&quot;Bonus Malus&quot;];<br />		[[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@&quot;fond.jpg&quot;]]];<br />		<br />		NSString *path = [[NSBundle mainBundle] pathForResource:@&quot;bm&quot; ofType:@&quot;plist&quot;];<br />		NSData *bmData = [NSData dataWithContentsOfFile:path];<br />		[self setBmArray:[[NSArray alloc] initWithArray:[NSPropertyListSerialization propertyListFromData:bmData mutabilityOption:NSPropertyListImmutable format:nil errorDescription:nil]]];<br />&nbsp; &nbsp; }<br />&nbsp; &nbsp; return self;<br />}


Clang me dit, par contre, que mon bmArray est un "leaked object", alors que j'ai bien ceci :
- (void)dealloc {<br />	[bmArray dealloc];<br />&nbsp; &nbsp; [super dealloc];<br />}


Evidemment, j'ai essayé de faire un [NSArray arrayWithArray] mais le reste du programme plante, vu que le NSArray n'a pas de mémoire alloué.

Vous feriez quoi vous, pour alloué un ivar sans avoir d'erreur de la part de Clang ?


PS: J'ai pensé à  retirer l'ivar et aller chercher les informations dans la methode cellForRowAtIndexPath: mais c'est idiot vue qu'on accède N fois au fichier. J'ai pas vraiment fait de tests, mais ça fait sale, mais si ça marcherai.

Adrien

Réponses

  • mpergandmpergand Membre
    00:01 modifié #2
    l'ai fort ce Clang  :)

    [bmArray release];
  • yoannyoann Membre
    00:01 modifié #3
    comment est définie ton setter ? Si tu fait un retain dans ton setter en effet tu as un problème de mémoire, si tu fait un assign il n'y en a pas. (pour faire simple)

    Le mieux serait que tu fasse un setter avec retain et que dans ton init tu passe par un pointeur intermédiaire que tu alloc/init, enssuite tu l'assigne via le setter et ensuite tu release le pointeur temporaire
  • schlumschlum Membre
    00:01 modifié #4
    Les "dealloc" ne doivent jamais être appelés directement comme ça... (d'ailleurs, je suppose qu'ils sont ignorés si le retain count est >0).
  • AdauAdau Membre
    00:01 modifié #5
    dans 1249492657:

    l'ai fort ce Clang  :)

    [bmArray release];


    Si je fais ceci, je plante tout mon programme.
    Yoann m'a soufflé LA bonne idée. Mon setter était en (assign, nonatomic).

    J'avais déjà  essayer de passer par un pointeur intermédiaire, mais si le setter est en assign, c'est sur que c'était inutile...

    Merci encore à  vous pour vos réponses pertinentes.

    Adrien
  • yoannyoann Membre
    00:01 modifié #6
    En soit si le setter était en assign il n'y avait pas de fuite mémoire hormis le release manquant dans le dealloc que je n'avais pas vu

    Ton dealloc doit être comme ça :

    - (void)dealloc {<br />	[bmArray release];<br />&nbsp; &nbsp; [super dealloc];<br />}
    


    ou encore

    - (void)dealloc {<br />	self.bmArray=nil;<br />&nbsp; &nbsp; [super dealloc];<br />}
    


    pour libérer ta mémoire
  • psychoh13psychoh13 Mothership Developer Membre
    00:01 modifié #7
    dans 1249494722:

    Les "dealloc" ne doivent jamais être appelés directement comme ça... (d'ailleurs, je suppose qu'ils sont ignorés si le retain count est >0).
    [/quote

    Même pas en rêve. Tu envoies -dealloc à  un objet normal (qui a le dealloc par défaut), ton objet sera supprimer et envoyer des messages à  ton object après fera planter ton application. Il n'y a aucun vérification du retainCount.
Connectez-vous ou Inscrivez-vous pour répondre.