Mit der Variablen der AppDelegate als eine Globale Variable - Frage bezüglich release/retain
Habe ich eine Variable namens "myDBManager" in meiner AppDelegate:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
MyDBManager *myDBManager;
}
@property (nonatomic, retain) MyDBManager *myDBManager;
@end
welches ich in den meisten anderen Klassen als Globale Variable halten alle meine kritischen Daten der Anwendung. Es wird nur einmal erstellt, und stirbt am Ende nur. So zum Beispiel zu bekommen, um die myDBManager in 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];
}
Hier ist meine Frage: während alle anderen lokalen Variablen AnyOtherClass, wie "otherVar" veröffentlicht, in der dealloc-Methode frei von AnyOtherClass (immer - ist das richtig?), die Freigabe myDBManager innerhalb AnyOtherClass führt zu Fehlern in der app.
So dass ich NIE lassen Sie die lokalen myDBManager variable in einer Klasse von meinem app - alle anderen lokalen Variablen werden immer veröffentlicht - und es funktioniert gut. (Auch die überprüfung der retainCount).
Bin ich im Recht, dass ALLE lokalen Variablen von Klassen, die freigegeben werden müssen in der dealloc dieser Klasse, oder ist es eigentlich OK, nicht zu release diese Variablen überhaupt in den Fällen der Verwendung einer globalen Variablen Konstrukt wie beschrieben? (oder Fälle?)
Vielen Dank für Ihre Hilfe!
InformationsquelleAutor user387184 | 2010-07-08
Du musst angemeldet sein, um einen Kommentar abzugeben.
In Ihrem Szenario
myDBManager
ist nicht eine Globale oder eine lokale variable, es ist ein auto-Vorbehaltsware (markiert mitretain
). Nach Die Objective-C-Programmierung Sprache: Deklarierte Eigenschaften,nonatomic,retain
Eigenschaften müssen ausdrücklich freigegeben werden indealloc
. Allerdings, wenn Sie Ihre Immobilie synthetisiert wird, die Sie nicht haben Zugang zu den backing member-variable, so können Sie nicht rufenrelease
; Sie müssen mit dem property-setter, um es zunil
, die schickenrelease
auf den vorherigen Wert. Sind Sie zufällig die Einstellung dermyDBManager
Eigenschaft inAnyOtherClass
undmyAppDelegate
zunil
?Update: @Don die Antwort ist eigentlich richtig. Sie sind nicht berufen die Eigenschaft setter (
self.myDBManager
), so dass die auto-behalten nicht kick in. Ich lasse meine Antwort, damit die Menschen lernen aus meinem Fehler. 🙂InformationsquelleAutor Franci Penov
Haben Sie nicht bewahrt, wenn Sie auf es in AnyOtherClass, so ist es Ihnen nicht zu release an diesem Punkt. Sie setzen die ivar direkt, so ist die Zurückbehaltung der Immobilie nicht ins Spiel kommen. Wenn Sie angerufen
würden Sie behalten und Sie haben, um Sie freizugeben, wenn Sie dealloc der Klasse.
Aber, wenn es eine Globale variable ist, warum nicht verwenden es auf diese Weise in AnyOtherClass? Warum nicht rufen Sie
mainDelegate.myDBManager
wenn Sie Sie brauchen, die DB-manager?Nein, wenn erklären Sie die Eigenschaft als
retain
sollte man immer behalten, und dann lassen Sie es in dealloc. So verschaffen Sie sich konsistent Verhalten, ob Sie ihn direkt in Ihre Klasse oder die Eigenschaft aufgerufen wird. Wirklich, sollten Sie immerself.property
um sicherzustellen, dass es wirkt, als Sie erwarten. Aber Siehe Franci ' s Antwort für eine ausführliche Erklärung, Wann man was tun sollte.Klarer zu werden: wenn Sie nicht verwenden Sie die-Eigenschaft, sollten Sie dies ändern:
myDBManager = mainDelegate.myDBManager;
:myDBManager = [mainDelegate.myDBManager retain];
Aber ich würde noch empfehlenself.myDBManager = mainDelegate.myDBManager;
Ich konnte nicht bekommen haben, eine bessere Erklärung! Vielen Dank!!!!
InformationsquelleAutor Don