2009-09-14 3 views
3

Lorsque vous libérez un objet dans Objective-C (en supposant que son nombre de versions est 1), son nombre de versions est décrémenté à 0 et la méthode dealloc appelée. L'objet est-il détruit juste là et après le [super dealloc], ou est-il ajouté au pool et détruit quand le pool est drainé? Je suppose que les objets libérés sont détruits à la fin de dealloc (quand [super dealloc] est appelé) Je sais que les variables autorelease sont ajoutées au pool, je voulais juste être sûr de ce qui arrive aux objets normaux libérés.Quand les objets libérés sont-ils finalement détruits?

acclamations -Gary-

+0

Dans quel environnement? –

+0

Désolé Rafal, Édité pour inclure Objective-C – fuzzygoat

+0

Cela vaut vraiment la peine de mentionner ici que le nombre de retenues n'atteint jamais 0. Lorsque vous faites la version finale, la décimation de 1 à 0 est une perte de temps CPU (: – Jacob

Répondre

8

Tout d'abord, Objective-C le langage de programmation n'a aucun concept de gestion de la mémoire. La gestion de la mémoire est intégrée dans la base de données (cadre commun de Cocoa pour Mac OS X et Cocoa Touch sur iPhone OS). Foundation ajoute un NSObject de classe de racine qui implémente alloc, retain, release et autorelease comme wrappers de commodité au-dessus des fonctions class_createInstance() et object_dispose() de l'exécution Objective-C. Depuis Objective-C est agnostique de gestion de la mémoire, l'ajout de garbage collection et rendant toutes les méthodes de gestion de la mémoire sur NSObject no-ops était assez facile. Mais il n'y a pas de ramasse-miettes sur iPhone OS et sur Mac OS X hérité et nous utilisons plutôt un schéma de comptage de référence dans Cocoa.

Un objet est créé lors de l'appel de la méthode de classe alloc sur NSObject ou NSProxy à partir de Foundation. Ces implémentations par défaut appellera class_createInstance() de sorte que vous n'avez jamais besoin de manuellement.

Un objet "meurt" lorsque dealloc est exécuté sur la classe racine NSObject. Ceci est lorsque la mémoire de l'objet sur le tas est libéré en appelant object_dispose(), vous ne devez appeler cette fonction vous aussi longtemps que vous héritez de NSObject ou NSProxy de la Fondation.

Les objets libérés ne sont pas traités de manière spéciale en ce qui concerne l'exécution, un objet autoreleased est tout aussi vivant que n'importe quel autre objet. Qu'est-ce qui se passe quand vous autorelease un objet est environ;

-(id)autorelease; { 
    [NSAutoreleasePool addObject:self]; // retain count +1 
    [self release];      // retain count -1 
    return self; 
} 

appel autorelease ne décrémenter le conserver nombre, il sera tout simplement transférer la propriété de l'objet de l'appelant à la piscine actuelle autorelease. Plus tard, lorsque le pool d'autorelease en cours disparaîtra, il appellera release sur tous les objets dont il est propriétaire, et tout objet qui n'appartient plus à rien d'autre est libéré.

+0

Donc, en Objective-C, il y a toujours une méthode dealloc même si une méthode personnalisée n'est pas définie. , keep count va à 0, dealloc appelé, [super dealloc] appelé, objet mort? – fuzzygoat

+0

Oui et Non. J'ai édité ma réponse pour clarifier la différence entre Objective-C et Cocoa. – PeyloW

5

Oui, ils sont désattribuées dès que le comptage frappe conserver zéro. Le système autorelease est pour les objets dont la propriété est un peu "ambiguë" - c'est-à-dire quand vous renvoyez un objet frais que vous ne voulez pas posséder, dont la durée de vie est inconnue, et vous ne voulez pas supposer l'appelant prendra la responsabilité de. Lorsque le pool d'autorelease est drainé (généralement la prochaine fois autour de la boucle d'exécution), tous les membres sont envoyés en diffusion. Si l'appelant qui a reçu votre objet veut en prendre la responsabilité, tout ce dont il a besoin est de le conserver, ce qui évitera son désengagement.

+0

[release d'objet]; Release count mis à 0; dealloc appelé (pour libérer toutes les variables d'instance); objet désalloué; .... est-ce que cela sonne bien? – fuzzygoat

+0

Yup, me semble bien, bien sûr, les implémentations personnalisées de dealloc peuvent faire n'importe quoi –

+0

Le pool d'autorelease des threads actuels est drainé à la fin de la boucle d'exécution en cours, et non à la prochaine exécution, car sinon ce thread pourrait conserver la mémoire très longtemps en attendant les minuteries, les événements utilisateur et autres. – PeyloW

Questions connexes