À l'aide de la Variable de AppDelegate comme une Variable Globale - question concernant la libération/retenir
J'ai créé une Variable appelée "myDBManager" dans mon AppDelegate:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
MyDBManager *myDBManager;
}
@property (nonatomic, retain) MyDBManager *myDBManager;
@end
que j'utilise dans la plupart des autres classes comme une Variable globale contenant tous mes critique des données d'application. Il obtient seulement créé une fois et meurt à la fin seulement. Ainsi, par exemple, pour se rendre à l'myDBManager dans AnyOtherClass
@interface AnyOtherClass : UITableViewController {
MyDBManager *myDBManager;
NSObject *otherVar;
}
@property (nonatomic,retain) MyDBManager *myDBManager;
@property (nonatomic,retain) NSObject *otherVar;
@end
//getting the data from "global" myDBManager and putting it into local var of AnyOtherClass
- (void)viewWillAppear:(BOOL)animated {
//get the myDBManager global Object
MyAppDelegate *mainDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];
myDBManager = mainDelegate.myDBManager;
}
- (void)dealloc {
[otherVar release];
//[dancesDBManager release]; DO NOT RELEASE THIS SINCE ITS USED AS A GLOBAL VARIABLE!
[super dealloc];
}
Voici ma question: alors que toutes les autres variables locales de AnyOtherClass, tels que "otherVar" doivent être libérés dans le dealloc méthode de AnyOtherClass (toujours - est-ce que le droit?), libérant myDBManager dans AnyOtherClass conduit à des erreurs dans l'application.
Donc je n'ai JAMAIS libérer le local myDBManager variable dans toutes les classes de mon app - toutes les autres variables locales sont toujours en liberté, et il fonctionne très bien. (Même vérifier les retainCount).
Suis-je en droit, que TOUTES les variables locales de classes ont besoin d'être libéré dans le dealloc de cette classe, ou est-il réellement OK, de ne pas relâcher ces variables du tout dans le cas de l'utilisation d'une variable globale construire comme décrit? (ou tout autre cas?)
Merci beaucoup pour votre aide!
OriginalL'auteur user387184 | 2010-07-08
Vous devez vous connecter pour publier un commentaire.
Dans votre scénario
myDBManager
est pas un ou une variable locale, c'est une auto-retenue à la propriété (marqué avecretain
). Selon L'Objective-C, Langage De Programmation: A Déclaré Propriétés,nonatomic,retain
propriétés doivent être libérées explicitement dansdealloc
. Toutefois, si votre propriété est synthétisé, vous n'avez pas accès à la sauvegarde de variable membre, donc vous ne pouvez pas appelerrelease
sur elle; vous devez utiliser la propriété setter pour le mettre ennil
, qui enverrarelease
à la valeur précédente. Êtes-vous, par hasard, le réglage de lamyDBManager
propriété dansAnyOtherClass
etmyAppDelegate
ànil
?Mise à jour: @Ne la réponse est correcte. Vous n'êtes pas en invoquant la propriété setter (
self.myDBManager
), de sorte que l'auto-conserver n'est pas un coup de pied dans. Je vais laisser ma réponse afin que les gens peuvent apprendre de mon erreur. 🙂OriginalL'auteur Franci Penov
Vous n'avez pas conservé lorsque vous faites référence dans AnyOtherClass, de sorte qu'il n'est pas le vôtre à la version à ce point. Vous êtes à la définition de la ivar directement, afin de le retenir sur la propriété ne viennent pas en jouer. Si vous avez appelé
vous serait retenue et elle devra le libérer lorsque vous dealloc la classe.
Mais, si c'est une variable globale, pourquoi ne pas l'utiliser de cette façon dans AnyOtherClass? Pourquoi ne pas appeler
mainDelegate.myDBManager
lorsque vous avez besoin de la DB manager?Non, si vous déclarez la propriété
retain
, vous devez toujours conserver, puis relâchez-la dans le dealloc. De cette façon, vous obtenez conforme au comportement si vous définir directement dans votre classe ou la propriété est appelée. Vraiment, vous devriez toujours utiliserself.property
pour s'assurer qu'il agit comme vous vous attendez. Mais Voir Franci réponse pour une explication détaillée de quand ce que vous faites.Pour être plus clair: si vous n'utilisez pas la propriété, vous devez modifier ce:
myDBManager = mainDelegate.myDBManager;
:myDBManager = [mainDelegate.myDBManager retain];
Mais je voudrais encore vous recommandons deself.myDBManager = mainDelegate.myDBManager;
Je ne pouvais pas avoir une meilleure explication! Merci beaucoup!!!!
OriginalL'auteur Don