使用 AppDelegate 的变量作为全局变量 - 关于释放/保留的问题
我在 AppDelegate 中创建了一个名为“myDBManager”的变量:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
MyDBManager *myDBManager;
}
@property (nonatomic, retain) MyDBManager *myDBManager;
@end
我在大多数其他类中将其用作保存所有关键应用程序数据的全局变量。它只被创建一次,并且只在最后消亡。因此,例如要访问 AnyOtherClass 中的 myDBManager
@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];
}
这是我的问题:虽然 AnyOtherClass 的所有其他局部变量(例如“otherVar”)必须在 AnyOtherClass 的 dealloc 方法中释放(总是 - 是这样吗?),但在内部释放 myDBManager AnyOtherClass 会导致应用程序出现错误。
所以我从来没有在我的应用程序的任何类中释放本地 myDBManager 变量 - 所有其他本地变量总是被释放 - 并且它工作正常。 (甚至检查保留计数)。
我对吗,类的所有局部变量都需要在该类的 dealloc 中释放,或者在使用所描述的全局变量构造的情况下根本不释放这些变量实际上可以吗? (或任何其他情况?)
非常感谢您的帮助!
I have created a Variable called "myDBManager" in my AppDelegate:
@interface myAppDelegate : NSObject <UIApplicationDelegate> {
MyDBManager *myDBManager;
}
@property (nonatomic, retain) MyDBManager *myDBManager;
@end
which I use in most other classes as a global Variable holding all my critical application data. It gets only created once and dies at the end only. So for example to get to the 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];
}
Here is my question: while all other local variables of AnyOtherClass, such as "otherVar" have to be released in the dealloc method of AnyOtherClass (always- is that right?), releasing myDBManager within AnyOtherClass leads to errors in the app.
So I NEVER release the local myDBManager variable in any Class of my app - all other local variables are always released - and it works fine. (Even checking the retainCount).
Am I right, that ALL local variables of classes need to be released in the dealloc of that class, or is it actually OK, not to release these variables at all in cases of using a global variable construct as described? (or any other cases?)
Thanks very much for your help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在您的场景中,
myDBManager
不是全局变量或局部变量,它是一个自动保留的属性(用retain
标记)。根据 The Objective-C 编程语言:声明属性、nonatomic、retain
属性应在dealloc
中显式释放。但是,如果您的属性是综合的,则您无权访问支持成员变量,因此您无法对其调用release
;您必须使用属性设置器将其设置为nil
,这会将release
发送到先前的值。您是否有机会将AnyOtherClass
和myAppDelegate
中的myDBManager
属性设置为nil
?更新:@Don的回答实际上是正确的。您没有调用属性设置器 (
self.myDBManager
),因此自动保留不会启动。我将留下我的答案,以便人们可以从我的错误中吸取教训。 :-)In your scenario
myDBManager
is not a global or a local variable, it's an auto-retained property (marked withretain
). According to The Objective-C Programming Language: Declared Properties,nonatomic,retain
properties should be explicitly released indealloc
. However, if your property is synthesized, you don't have access to the backing member variable, thus you can't callrelease
on it; you have to use the property setter to set it tonil
, which will sendrelease
to the previous value. Are you by any chance setting themyDBManager
property inAnyOtherClass
andmyAppDelegate
tonil
?Update: @Don's answer is actually correct. You are not invoking the property setter (
self.myDBManager
), so the auto-retain does not kick in. I'll leave my answer so people can learn from my mistake. :-)当您在 AnyOtherClass 中引用它时,您还没有保留它,因此此时它不属于您的释放对象。您直接设置 ivar,因此该属性的保留不会发挥作用。如果您调用,
您将保留它,并且在释放该类时必须释放它。
但是,如果它是一个全局变量,为什么不在 AnyOtherClass 中以这种方式使用它呢?当您需要数据库管理器时,为什么不调用
mainDelegate.myDBManager
呢?You haven't retained it when you reference it in AnyOtherClass, so it is not yours to release at that point. You are setting the ivar directly, so the retain on the property does not come into play. If you called
you would be retaining it and would have to release it when you dealloc the class.
But, if it is a global variable, why not use it that way in AnyOtherClass? Why not call
mainDelegate.myDBManager
when you need the DB manager?