Cocoa Touch Question. Devrait [array NSMutableArray] être retenu?
-
13-09-2019 - |
Question
Voici l'essentiel de quelque code que je vous écris. Je crains que je ne traite pas correctement les retenir / libérer des problèmes avec la méthode de classe de tableau sur NSMutableArray. La mémoire suivante en fait une fuite?
for(a while) {
// do stuff
NSMutableArray *a = nil;
// do stuff
if (!a) {
a = [NSMutableArray array];
}
} // for(a while)
La solution
Vous ne fuite de mémoire dans ce code, et en libérant le tableau vous allez provoquer un plantage lorsque le tableau est autoreleased à la fin de la boucle d'exécution.
La plupart des classes de cacao offrent deux façons de faire un nouvel objet, et sont très compatibles avec cette convention:
-
[[NSSomeObject alloc] init]
: vous êtes responsable de la libération de l'objet (par exemple méthode) .
-
[NSSomeObject someObject]
: l'objet sera autoreleased pour vous, généralement à la fin de la boucle d'exécution (méthode de classe). Il 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 des méthodes pratiques, autant que possible pour améliorer les performances. Ceci est controversée conseil, ne peut pas gagner beaucoup de temps processeur, et sépare la alloc-init de la version sur un objet que vous ne se soucient pas en fait beaucoup à garder.
Autres conseils
De la
Oui, si vous voulez rester dans les parages. L'objet retourné est un objet autoreleased qui se désallouée lorsque son pool autorelease se purgé. Toutes les méthodes de classe de tableau qui commencent par « tableau » renvoient ces types d'objets autoreleased. Lisez ce doc par Apple.
C'est valide. Il peut aider à gérer simplement les choses manuellement lorsque vous avez des questions, d'apprendre.
Il existe une convention:
- préfixes (init init, 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, pour libérer ce que je peux sur le site d'appel, plutôt que de le pousser à autoreleased. Certains problèmes de autorelease deviennent alors douloureusement difficiles à traquer. Bien sûr, autorelease est pratique pour le programmeur dans ce cas (rien prévu va mal), mais affecte négativement la réutilisation, la clarté et la performance (moreso dans les grandes codebases / programmes).