2010-09-28 4 views
0

Au moment où je pensais avoir complètement compris ce sujet, je suis de retour aux sources.Méthodes qui appellent méthodes: bases de Autorelease?

J'ai une méthode qui instancie un objet autoreleased, en utilisant (par exemple) stringWithFormat:

return [NSString stringWithFormat:@"what"]; 

J'appelle cette méthode d'une autre méthode, et une autre méthode, chaque fois retourner ce autoreleased NSString et dans chaque niveau de la hiérarchie. Le code fonctionne correctement et l'instance NSString est intacte à chaque niveau de la hiérarchie.

I pensé que depuis l'instance est autoreleased, il pourrait se terminer brusquement avec un retainCount de 0 à un point quelconque dans la pile d'appel (à savoir, l'une des méthodes travailleraient sur un objet libéré). Est-il vrai que je ne peux pas dépendre de cet objet?

Modifier: Je réalise que la question n'était pas trop claire. Pardon. Je veux dire:

Method1 ---calls---> Method2 ---calls---> Method3 ---instantiates the string---> 
+0

Vous ne verrez probablement jamais un nombre de retenues de 0. Si un objet a un nombre de retenues de 1 lorsque la libération est appelée, il est désalloué au lieu de décrémenter le nombre de rétention. De plus, dans l'exemple, stringWithFormat pourrait être assez intelligent pour renvoyer le littéral transmis car il ne contient aucun spécificateur de format. – JeremyP

+0

@JeremyP, bon point sur les comptes retenus n'atteignant jamais zéro. D'un autre côté, mon exemple original était en fait 'return @" quoi ";', qui est le même dans cet exemple, je pense. –

Répondre

1

Il est sûr de supposer qu'un objet auto-libéré ne sera pas libéré dans une trame de pile en dessous de l'image dans laquelle il a été alloué. Ainsi, dans une pile d'appel comme

method1 
    method2 <== instance allocated/autoreleased here 
    method3 <== safe to use here 

il est sûr de supposer une instance alloc/autoreleased dans method2 est valable dans MÉTHODE3 à moins que vous jouez de vilains tours et de drain d'une piscine créée en method1 de MÉTHODE3. C'est parce qu'un pool autorelease dans un cadre supérieur ne peut pas être drainé (sauf par stupidité) dans un cadre inférieur. Bien sûr, une fois que le contrôle revient à la méthode 1, tous les paris sont désactivés.

Les pools de libération automatique alloués dans une trame inférieure ne contiendront pas l'instance libérée dans la méthode 2 car ils ne pourraient pas avoir été le pool actif (ils n'ont pas encore été créés!) Au moment de la libération automatique.

Enfin, à moins une méthode plus faible dans la chaîne d'appel, entre la méthode d'intérêt et la méthode qui instancie et autoreleases une instance d'objet crée et draine une piscine autorelease, vous êtes assuré que la piscine englobante ne sera pas être drainé jusqu'à la fin de la boucle de course.

+0

Encore une bonne réponse. Merci. –

4

La réponse est que la NSAutoreleasePool est évacuée après tous les appels de méthode et vous êtes de retour dans la boucle d'exécution. Cela signifie que dans une pile d'appels, l'objet ne sera pas libéré tant que vous ne revenez pas à la boucle d'exécution.

+0

Est-ce une garantie si je ne vidange pas le pool autorelease, ou est-ce juste ce qui se passe? –

+2

C'est une garantie fondamentale. Les pools Autorelease ne s'auto-vidangent pas automatiquement. Si c'était le cas, la notion même d'objet auto-libéré serait entièrement brisée et inutilisable. – bbum

+1

C'est une garantie. Vous devriez être sûr d'utiliser l'objet pour le reste de la boucle d'exécution. –

Questions connexes