Je l'ai déjà voté sur la bonne réponse, j'ajoute cela comme une note de style:
Votre code d'appel ne va pas travailler, parce qu'il appelle [object description]
quand il devrait appeler [object test]
Vous n'avez pas besoin de renvoyer des chaînes mutables à moins que vous ne souhaitiez vraiment pouvoir modifier la chaîne. J'essaie personnellement de minimiser la mutabilité dans le code que j'écris parce que je pense qu'il est plus facile de maintenir des programmes où les changements d'état sont minimes. Vous ne renvoyez qu'une description, donc je ne pense pas qu'elle doive être modifiable. Je sais que ce n'est que quelques exemples de code alors peut-être que je suis trop pointilleux
Vous pouvez réécrire ce que:
-(NSString *)description {
// Just return a static NSString. No need to worry about memory management.
return @"Test Value";
}
Et si vous voulez être en mesure de changer la valeur de ce retour chaîne dans votre code d'appel:
NSMutableString *testVar = [[NSMutableString alloc]initWithString:[object description]];
Puisque vous avez appelé alloc sur cette chaîne, vous possédez et sont responsables de le libérer à une date ultérieure.
Vous pouvez également utiliser l'un de mes morceaux préférés de code:
NSMutableString *testVar = [[object description] mutableCopy];
Ceci renvoie une copie mutable de même un objet immuable (si elle est conforme au protocole NSMutableCopying, bien sûr). Et vous devez envoyer [testVar release]
à un certain stade.
Et pour lier cela en tant que réponse réelle à votre question: si vous envoyez alloc, copie, mutableCopy ou conserver à un objet, vous possédez l'objet et que vous êtes responsable de l'envoi c'est un message version. Vous pouvez supposer que toute autre chose renvoie un objet autoreleased. Encore une fois, je sais que ce n'est qu'un petit échantillon de code sur lequel vous avez posé une question, mais si vous suivez la règle ci-dessus, la plupart de vos problèmes de gestion de la mémoire sont triés. Dans votre premier exemple, vous n'en avez envoyé aucun pour les messages, vous n'avez donc pas besoin de libérer de la mémoire vous-même. Cependant, vous avez un alloc
dans votre code d'appel, donc vous possédez testVar
et vous devez le libérer.
+1 Cela répond à la question – Abizern
Vous avez raison, mais essayez d'éviter de parler des comptes, ils sont un faux-fuyant - il n'y a aucune garantie que NSMutableString retournera un objet autoreleased, seulement qu'il renvoie une chaîne mutable que vous ne possède pas actuellement. Vous pouvez retourner le résultat à votre invocateur simplement parce que les règles de gestion de la mémoire indiquent explicitement que "cette méthode peut également renvoyer l'objet à son invocateur en toute sécurité". –
C'est un bon point. Je trouve que penser en termes de comptes de retenue est pratique pour expliquer les choses. Vous avez raison - tout ce que vous savez, c'est que stringWithString renvoie un objet appartenant à quelqu'un d'autre. Dans ce cas, puisque NSMutableString a réellement alloué l'objet, c'est la responsabilité de NSMutableString de le libérer. J'ai cependant eu l'impression que ces constructeurs de commodité (constructeurs non-init) renvoient conventionnellement des objets auto-libérés. Je serais surpris si je tombais sur un qui ne se comporte pas comme ça. –