views:

43

answers:

2

Hello,

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!

A: 

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

self.myDBManager = mainDelegate.myDBManager;

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?

Don
...because using "mainDelegate.myDBManager" requires "MyAppDelegate *mainDelegate = (MyAppDelegate *)[[UIApplication sharedApplication]delegate];"And that's too much text to be readable. The variable "myDBManager" is a local variable of "AnyOtherClass", so I can use it in all methods of this class easily.But thanks for that clarification! So I NEVER release if a ivar JUST gets assigned without the "self.xx"! (certainly I need to release if it was alloced - but thats a different case) Is that right?
No, if you declare the property as `retain`, you should always retain it and then release it in dealloc. That way, you get consistent behavoir whether you set it directly in your class or the property is called. Really, you should always use `self.property` to ensure it acts as you expect. But See Franci's answer for detailed explanation of when you should do what.
Don
To be clearer: if you do not use the property, you should change this: `myDBManager = mainDelegate.myDBManager;` to this: `myDBManager = [mainDelegate.myDBManager retain];` But I'd still recommend `self.myDBManager = mainDelegate.myDBManager;`
Don
I could not have gotten a better explanation!Thanks so much!!!!
A: 

In your scenario myDBManager is not a global or a local variable, it's an auto-retained property (marked with retain). According to The Objective-C Programming Language: Declared Properties, nonatomic,retain properties should be explicitly released in dealloc. However, if your property is synthesized, you don't have access to the backing member variable, thus you can't call release on it; you have to use the property setter to set it to nil, which will send release to the previous value. Are you by any chance setting the myDBManager property in AnyOtherClass and myAppDelegate to nil?

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. :-)

Franci Penov