2009-06-13 8 views
4

Voici l'essentiel d'un code que j'écris. Je suis préoccupé par le fait que je ne traite pas correctement les problèmes de conservation/publication avec la méthode de classe array sur NSMutableArray. La fuite de mémoire suivante est-elle réelle?Cocoa Touch Question. Should [NSMutableArray array] doit-il être conservé?

for(a while) { 
    // do stuff 
    NSMutableArray *a = nil; 
    // do stuff 
    if (!a) { 
     a = [NSMutableArray array]; 
    } 
} // for(a while) 

Répondre

12

Vous ne fuite de mémoire dans ce code, et en libérant le tableau vous provoquera un plantage lorsque le tableau est autoreleased à la fin de la boucle d'exécution.

La plupart des classes Cocoa fournissent deux façons de faire un nouvel objet, et sont très compatibles avec cette convention:

  1. [[NSSomeObject alloc] init]: vous êtes responsable de la libération de l'objet (par exemple méthode).

  2. [NSSomeObject someObject]: l'objet sera automatiquement libéré pour vous, généralement à la fin de la boucle d'exécution (méthode de classe). C'est à peu près équivalent à [[[NSSomeObject alloc] init] autorelease].

L'utilisation correcte de la méthode d'instance serait:

a = [[NSMutableArray alloc] init]; 
// do stuff 
[a release]; 

L'utilisation correcte de la méthode de classe serait:

a = [NSMutableArray array]; 
// do stuff, array is in the autorelease pool 

Notez qu'Apple vous a recommandé de rester loin de les méthodes de commodité autant que possible pour améliorer les performances. Ceci est controversial advice, peut ne pas économiser beaucoup de temps processeur, et sépare l'alloc-init de la version sur un objet que vous ne vous souciez pas vraiment de garder.

+0

Excellent ensemble de réponses. Merci beaucoup. – dugla

+0

Salut, Je suis arrivé à une conclusion de votre réponse. S'il vous plaît dites-moi, j'ai raison? Donc, il est bon d'allouer et libérer de la mémoire que autorelease pour la programmation iPhone. Nous devrions utiliser des méthodes moins autorelease. Merci. –

+0

Oui, vous devriez limiter votre utilisation de 'autorelease'. C'est pratique, mais les objets auto libérés resteront dans le pool autorelease jusqu'à la prochaine fois sur la boucle d'exécution. Les objets explicitement libérés seront désalloués plus ou moins immédiatement. –

6

De l'Cocoa Memory Managment Rules:

Vous prenez possession d'un objet si vous créez à l'aide d'une méthode dont le nom commence par « alloc » ou « nouveau » ou contient « copie » (par exemple, alloc, newObject ou mutableCopy), ou si vous lui envoyez un message de conservation. Vous êtes responsable de renoncer à la propriété des objets que vous possédez en utilisant la libération ou autorelease. Toute autre fois que vous recevez un objet, vous ne devez pas le libérer.

donc avec la ligne:

a = [NSMutableArray array]; 

vous ne prenez pas la propriété du tableau, et il vous sera transmis à autoreleased. La mémoire sera traitée automatiquement pour vous par le pool autorelease, et une fois qu'elle n'est plus utilisée, elle sera libérée pour vous. Si vous souhaitez conserver le tableau en dehors de l'événement en cours, vous devez le conserver, sinon il sera libéré pour vous.

2

Oui, si vous voulez qu'il reste.

L'objet renvoyé est un objet auto-libéré qui sera désalloué lorsque son pool de libération automatique sera purgé.

Toutes les méthodes de classe de tableau qui commencent par "tableau" renvoient ces types d'objets auto-libérés.

Lire cette doc par Apple

0

Cela est valide. Il peut être utile de gérer les choses manuellement lorsque vous avez des questions à apprendre.

Il y a une convention:

  • préfixes init (initialisation, initWithString :) indique un nombre de retenir 1, où
  • préfixes objectname (string, stringWithString :) indique un objet autoreleased

J'ai eu l'habitude, pendant des années, de libérer ce que je peux sur le site d'appel, plutôt que de le pousser à être auto-libéré. Certains problèmes d'autorelease deviennent alors difficiles à traquer. Bien sûr, autorelease est une commodité pour le programmeur dans ce cas (à condition que rien ne se passe mal), mais affecte négativement la réutilisation, la clarté et la performance (plus dans les grands bases de code/programmes).

Questions connexes