2009-09-02 3 views
1

Je n'arrive pas à comprendre pourquoi NSLog signale «chien» lorsque le code est exécuté. Je comprends à propos de retenir les comptes et dealloc e.t.c. Quelle simple chose me manque?Objet ne libérant pas l'objectif C

NSString *newFoo = @"dog"; 
[newFoo release]; 
NSLog(newFoo); 
+0

Merci pour la réponse. J'essayais juste de me familiariser avec Objective-c et j'écrivais ceci pour voir si je comprenais ce qui se passait. –

+0

@Spyker Vous devriez marquer une réponse comme acceptée :-) – chakrit

+1

Pourquoi y a-t-il tant de gens qui disent "je ne sais pas Objective-C mais" et ensuite faire des hypothèses sur sa mise en œuvre? Si vous n'avez pas la réponse à coup sûr, cela ne sert à rien de répondre. Le bouton dit "Postez votre réponse", pas "Publiez votre réponse" ou "Publiez votre hypothèse". – dreamlax

Répondre

7
[@"String Literal" release]; 

est un noop;

NSString *literal = @"String Literal"; 
[literal release]; 

est également un noop. C'est seulement le cas pour les littéraux de chaîne; et vous ne devriez jamais vous attendre à ce comportement ailleurs. (C'est-à-dire, même si vous dites à l'objet de libérer, il ne le fait pas.)

+0

Exactement, même si vous l'avez peut-être déclaré plus clairement que moi. –

+2

Et vous ne devriez certainement jamais considérer ce comportement lors de la programmation. Le nombre de retenues est un détail d'implémentation, la seule chose dont vous devez vous soucier est d'équilibrer vos retenues avec vos versions. – bbum

-1

Vous de-allocation du bloc de mémoire à, mais les données sont toujours là le pointage du pointeur.

Le relâchement ne fait pas automatiquement disparaître cette partie de la mémoire.

Donc, vous pouvez toujours lire les données mais c'est juste peut être coincé (alloué) par quelque chose d'autre sur la ligne ... mais pas encore. Je ne suis pas un codeur ObjC par le commerce mais comme depuis sa compatibilité avec C c'est ce que je pense de mon expérience en C.

+0

Le pointeur n'est pas désalloué – Mark

+0

Uniquement par un cas spécial pour les littéraux de chaîne. Changer cela à toute autre classe et tout autre schéma d'initialisation et chakrit est 100% correct. – Randolpho

+0

Un défaut et vous obtenez une rafale de downvotes. Je suppose que c'est ce que signifie "communauté". – chakrit

5

Je crois que c'est parce que @ "dog" est efficacement traité comme une constante par le compilateur. Il crée une sous-classe de NSString (qui est un cluster de classe) qui persiste pendant la durée de vie de l'application. Je viens de découvrir this question pour la réponse définitive, qui est essentiellement la même que la mienne.

-1

Bien que l'objet soit probablement publié (je ne sais pas comment Obj-C gère les chaînes en interne, certaines langues mettent fondamentalement en cache les chaînes), vous n'avez rien écrit de nouveau dans la mémoire de newFoo après l'avoir publié. La mémoire dans laquelle la chaîne a été stockée conserve son contenu, mais peut être écrasée à tout moment.

newFoo pointe encore à la même adresse en mémoire, mais cette mémoire pourrait devenir n'importe quoi d'autre à tout moment.

La manière de s'assurer que vous ne pointez pas sur la mémoire potentiellement sale est de régler newFoo à nil après l'avoir relâché.

2

Une chaîne est un cas particulier .. http://thaesofereode.info/clocFAQ/

Mais en général, en supposant que vous n'utilisez pas la collecte des ordures juste coller aux quelques règles simples ..

http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/MemoryMgmt/MemoryMgmt.html

plus .. pertinemment retenez un objet quand vous en avez besoin pour le maintenir - balancez-le avec un relâchement une fois terminé. Si vous ne l'avez pas créé ou conservé, vous n'avez pas besoin de le libérer. Envoi -release à un objet n'est pas comme libérer de la mémoire, il signale seulement que vous en avez fini avec lui. Il se peut qu'il soit toujours là ou non. Vous n'avez aucun moyen de le savoir, vous n'avez pas besoin de le savoir, et vous ne devriez pas essayer de savoir s'il est utilisé ailleurs, si un code pomme intelligent a décidé de le mettre en cache, s'il s'agit d'un singleton, etc.

Il peut toujours être valide, mais lorsque vous avez envoyé la version, vous avez effectivement dit "J'ai terminé" et non "récupérer cette mémoire".

Questions connexes