Objective-C - Test pour l'instance de l'objet en cours de dealloced/libéré
Il y a une certaine façon de tester un objectif-c exemple pour être dealloced/libéré (retain count == 0)??
Par exemple, l'objet A avoir une référence (pointeur) de l'objet B, mais l'objet B peut être libéré dans la mémoire de faibles niveaux, comment je test de référence B pour être sûr que c'était dealloced??
@interface A : NSObject {
B b;
}
@implementation A {
- (void) someAction:(id) sender {
//is b previously dealloced??
if ..... ???? {
b = [[B alloc] init];
}
//continue
}
}
Merci!!
Il sonne comme cet article peut vous montrer comment faire: Exécuter du Code lors de la Désallocation de l'Objet
OriginalL'auteur jlpiedrahita | 2009-06-11
Vous devez vous connecter pour publier un commentaire.
Vous ne pouvez pas tester si un objet a été dealloced puisque, évidemment, l'objet n'est pas là pour parler plus. Si vous définissez
b
à zéro lorsque vous la relâchez (par exemple, en faisantself.b = nil
), bien que, vous pouvez tester le néant et créer l'objet ensuite.Quel est le cadre de la classe est la libération de cette classe de la variable d'instance? Pourquoi n'est-ce pas la classe de ses propres ivar? Je pense que vous pourriez avoir besoin de fournir plus d'info dans la question. Comme Alex l'a dit, vos attributs ne devriez pas être en train de disparaître mystérieusement.
OriginalL'auteur Chuck
Si vous définissez la
NSZombieEnabled
variable d'environnement, puis dealloced les objets deviennent des instances deNSZombie
. Ces jeter quand ils sont à côté messaged, l'origine de votre code à crash and burn - exactement ce que vous avez besoin de déboguer cette situation.http://www.cocoadev.com/index.pl?DebuggingAutorelease
Mise à jour: Pour XCode 4.0 voir Comment faire pour activer NSZombie dans Xcode?
OriginalL'auteur
Puisque la variable
b
est totalement interne à la classeA
, et n'est pas déclarée comme@public
(la valeur par défaut est@protected
), la meilleure façon de savoir sib
a été libéré est de libérer et de définir le pointeur ànil
. De cette façon, vous pouvez simplement vérifierif (b == nil)
et de créer une nouvelle instance, si nécessaire.La grande question, cependant, est ce que la vraie nature et le comportement de la mémoire de
b
est. Vous dites que "l'objet B peut être libéré dans la mémoire de faibles niveaux", mais n'explique pas pourquoi. Si vous êtes en utilisant le standard de locutions pour conserver la libération en Objective-C, je pense que l'Un serait le seul à déterminer si B doit être libéré, car il est en train de créer une nouvelle instance. Si vous n'avez pas l'intention pour Un de prendre de telles décisions, permettant d'attribuer un nouveau B conduira à la propriété de la confusion et de la mémoire de bugs en bas de la route.Si A est pas en charge de B, et si vous êtes sur Leopard (ou au-delà) et ont la collecte des ordures activé, ce que vous voulez, c'est un réinitialisation de référence faible. Ceci est déclarée à l'aide de
__weak
avant une variable d'instance de la déclaration, et n'empêche pas le garbage collector de la collecte de l'objet auquel il renvoie. (Une "forte" de référence est la valeur par défaut, et que le garbage collector ne désalloue de l'objet, on peut tracer à partir d'une racine à travers seulement de solides références.) En outre, le GC sera automatiquement réglée à la faiblesse des références à 0 pour vous si/quand l'objet est libéré.Revenir à "la grande question", à moins que
b
est déjà une référence faible et GC est sur, (et quelques autres conditions soute), le système va automatiquement libérer B pour vous. Si la raison de la désallocation deb
est que les instances de B croître au fil du temps, comme un cache des articles jetables), il serait beaucoup mieux d'avoir un moyen de vider B. Par exemple, mutable collections de la Fondation ont un-removeAllObjects
méthode. Une telle approche permettrait d'éviter la plupart de la confusion quant à savoir sib
existe toujours, et est beaucoup plus efficace qu'à plusieurs reprises (de)l'allocation des objets.L'une des variables est également "Cacao", et la question n'est pas de spécifier l'iPhone, donc je pense qu'il vaut mieux être général et de qualifier de "si" pour être utile à ceux qui, peut-être sur Leopard.
OriginalL'auteur Quinn Taylor
Si vous conservez b correctement, il ne sera pas libéré dans les conditions de mémoire faible.
Qui est, sauf si vous vous libérer vous-même, auquel cas il est important que vous supprimer manuellement toutes les références à celui-ci avant de le faire (en le remplaçant par ce néant)
Dans ce cas, il suffit de tester la valeur nil va faire:
Si il semble que vos objets sont en train d'être libéré automatiquement, alors vous avez besoin de revoir votre code pour vérifier que vous avez conservé suffisamment.
OriginalL'auteur Alex Brown
Vous pourriez essayer de mettre NSLog messages dans les objets
dealloc
méthode. Qui va au moins vous dire quand l'objet est libéré.OriginalL'auteur Abizern
qui serait un "try-catch"?
assez sûr d'appeler un message sur un dealloced instance ne PAS jeter un normal exception, plutôt que de promulguer une sigbart.
-1 pour libéré instance de ne PAS jeter l'exception.
OriginalL'auteur john ellis