2010-03-21 5 views
3

Je ne semble jamais avoir ce droit. J'ai une méthode qui retourne un tableau mutable. Quelle est la bonne façon de retourner le tableau et éviter les fuites de mémoire potentielles?Façon correcte de retourner un tableau

Si je prévois de stocker les résultats localement à l'intérieur d'un autre contrôleur de vue, est-ce que cela affecte la façon dont le tableau doit être renvoyé? Enfin, que se passe-t-il s'il s'agit simplement d'un tableau non mutable? Est-ce que cela nécessite une technique différente?

merci, Howie

+0

Le point entier de toutes ces grandes réponses est que, de la méthode d'appel, si vous ne le faites pas 'alloc' vous n » Je dois "libérer" ce qui signifie qu'il DOIT être auto-libéré. Je voulais aussi quitter ce lien http://developer.apple.com/fr/mac/library/documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH –

+0

yar: C'est un C'est un peu trompeur, car cela implique que vous devez le "autorelease", mais autoreleasing est effectivement le même que libérant (puisque c'est ce qu'il fait, mais pas immédiatement). Ce que vous vouliez dire, c'est qu'un objet créé par une méthode sans 'alloc',' new', ou 'copy' dans son sélecteur est déjà auto-libéré, donc vous pouvez juste le retourner. –

+0

@Peter Hosey, c'est ce que je voulais dire, ne voulait pas dire implicitement que vous auriez à le faire vous-même. Je voulais dire que la méthode appelée ... eh bien, vous savez ce que je voulais dire, votre commentaire est plus clair :) –

Répondre

4

Si votre méthode n'a pas d'alloc ou de copie dans le nom, la bonne chose est de renvoyer une version auto-libérée du tableau. En outre, vous devez retourner une copie du tableau afin d'éviter des modifications à votre copie locale

- (NSMutabalArray*] mutableArray { 
    return [[myArray mutableCopy] autorelease]; 
} 

- (NSArray*] array { 
    return [[myArray copy] autorelease]; 
} 
+0

merci - comme un suivi est-ce la même chose s'applique aux dictionnaires? – Ward

+0

Oui. Il est normalement vrai pour n'importe quelle classe de conteneur que vous devriez retourner une copie de mutableCopy, si vous avez besoin d'empêcher les changements apportés à la copie retournée d'affecter l'instance que vous avez dans votre classe. Certes, le mécanisme de copie n'est pas nécessaire si le conteneur est créé à l'intérieur de la méthode uniquement pour le retour, dans ce cas vous n'avez pas besoin de vous soucier de la copie. –

+2

Je signale à d'autres lecteurs que vous ne devriez normalement pas nommer une méthode 'getFoo', car le préfixe" get "dans le style Cocoa indique une méthode qui retourne une valeur par référence (comme' getRed: green: blue: alpha de NSColor : ', qui prend quatre pointeurs sur les variables CGColor dans lesquelles vous voulez placer les valeurs du composant). Voir http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html et http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/KeyValueCoding /Concepts/AccessorConventions.html. –

1

Pour NSMutableArray j'utiliser:

-(NSMutableArray*)getMyArray 
{ 
    NSMutableArray *retval = [[NSMutableArray alloc] init]; 
    // do your stuff w/ array 
    return [retval autorelease]; 
} 

L'appelant de ce code peut vouloir retain le tableau retourné, car il est autoreleased.

+0

Comme un NSMutableArray * est retourné, je vous recommande d'appeler 'copy' sur l'objet retourné sauf si vous voulez le tableau être capable de changer sous toi. – Abizern

+0

merci - quelle est la différence si je conserve le tableau retourné ou ne le conserve pas? C'est juste une question de ce que j'ai l'intention de faire avec cela afin que si je pourrais en avoir besoin plus tard, je devrais le conserver? – Ward

+0

Vous n'avez besoin de le 'retenir' que si vous voulez le conserver une fois la méthode d'appel terminée. Sinon, vous avez l'objet 'autoreleased' jusqu'à ce que votre méthode se termine. –

2

Renvoyer un objet auto-libéré. Si vous avez créé votre tableau avec toutes les méthodes alloc/init/copy - vous devriez envoyer le message autorelease au tableau avant de le retourner (quelque chose comme return [myArray autorelease];). Sinon, les tableaux créés avec les méthodes d'usine (arrayFrom...arrayWithContentsOf...) renvoient l'objet auto-libéré pour que vous n'ayez pas à vous soucier des fuites de mémoire.

Vous devriez vous renseigner sur la gestion de la mémoire et conserver le compte sur le site de développement apple. Il peut y avoir d'autres méthodes d'initialisation qui conservent l'objet retourné, ce qui provoquerait une fuite de mémoire.

Questions connexes