2010-09-30 4 views
1

J'essaie de comprendre un peu plus sur la gestion de la mémoire. Sachant que je dois libérer tout ce que j'INITou alloc'ed Je suis confus au sujet de ce qui suit:iPhone: Retour NSMutableArray dans la méthode tout en libérant

- (NSMutableArray *)getData { 
    NSMutableArray *data = [[NSMutableArray alloc] init]; 
    NSString *first = @"First object"; 
    [data addObject:first]; 
    NSString *second = @"Second object"; 
    [data addObject:second]; 

    return data; 

} 

Depuis je alloc et init, je sais que je dois libérer mon objet de données. Mais si j'ajoute autorelease à la partie init ou au retour, il se bloque lorsque j'exécute la méthode.

Quelle est la bonne façon de faire quelque chose comme ceci avec la gestion de la mémoire correcte pour iPhone?

+0

Pouvez-vous poster le message d'erreur de l'accident? La pile d'appels aiderait probablement aussi. –

Répondre

3

Vous devriez autorelease, comme vous l'avez dit. L'appelant a probablement besoin de conserver, comme celui-ci - en particulier en cas de stockage dans une variable d'instance:

NSMutableArray *array = [[obj getData] retain]; 

Plus tard, quand il est totalement fait avec elle:

[array release]; // balances the retain above 
+0

Cela a fonctionné, merci. Mais ce que je ne comprends pas, c'est que je mets cela dans un point qui est retenu. Pourquoi aurais-je besoin de retenir à nouveau? –

+0

@Nic Hubbard: Qu'est-ce qu'un "point qui est retenu"? – Chuck

+0

Je suis désolé, un pointeur. J'ai donc utilisé les missions @property (nonatomic, retain) NSMutableArray *; dans mon fichier .h. –

2

Vous êtes sur la bonne voie. Vous devez appairer chaque alloc/init avec release ou autorelease, ce qui provoque le nettoyage de l'objet dès que la référence finale disparaît.

Le modèle est quelque chose comme ceci:

- (SomeObject*)generateSomeObject 
{ 
    SomeObject* someObject = [[[SomeObject alloc] init] autorelease]; 
    ... 
    return someObject; 
} 
+0

J'ai essayé cela, mais il se bloque lorsque j'ajoute autorelease, avec rien dans la console de débogage. –

0

assignez le résultat que vous de cette méthode à une variable d'instance? Gardez à l'esprit que les éléments ajoutés au pool d'autorelease sont libérés à un moment donné (généralement à la fin de la boucle d'exécution). Par conséquent, si vous l'attribuez à une variable d'instance, la fin de la boucle d'exécution s'affiche. votre variable d'instance finira pointant vers la poubelle (ou parfois un objet différent) à moins que vous conserver il. Le nom de la méthode (getData) suggère que l'objet renvoyé doit être auto-libéré. ​​Vous pouvez donc créer le tableau avec [NSMutableArray array], le remplir comme d'habitude, puis le renvoyer de la méthode.

Si le code qui invoque getData veut le tableau pour survivre à une itération de la boucle d'exécution, il faut retain, mais aussi, il faut vous assurer de release le tableau quand il est enfin fini avec elle - ce qui est généralement fait dans votre méthode dealloc.

+0

Je l'utilise juste pour construire un tableau à partir de certains objets afin que je puisse garder tout ce code dans un autre fichier. Ensuite, dans la méthode viewDidLoad de mes applications, j'appelle cette méthode de classe qui renvoie le tableau, puis je l'attribue à un pointeur qui est conservé. Mal le faire? –

+0

@Nic: Si vous le retenez, alors vous le faites correctement. Etes-vous sûr que tout ce qui est contenu dans le tableau est également correctement géré? – dreamlax

+0

Vérifiez le poste ci-dessus pour voir ce qui a fonctionné. Je devais retenir l'appelant. –

Questions connexes