Reputation: 35318
I haven't done any iOS development since iOS 3, so my memory is a little hazy (though memory management was never anything I struggled with and my mind is quite clear on that).
I'm starting a new project and don't understand why the skeleton code is structured the way it is:
- (void)dealloc
{
[_window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]]
autorelease];
// ... snip ...
}
_window
come from? Is this just another way to access [self window]
?I'd have written this as:
- (void)dealloc
{
[self.window release];
[super dealloc];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc]
initWithFrame:[[UIScreen mainScreen] bounds]];
// ... snip ...
}
It was always drummed into me never to release an autoreleased object, and in fact doing so usually results in a segmentation fault.
Upvotes: 3
Views: 420
Reputation: 34286
1. Why would the window object be autoreleased? I'm pretty sure it never used to be this way in older iOS versions.
If window object is not autoreleased, then it results in leak. Since you are using
self.window = [[[UIWindow alloc] ....]autorelease];
self.
syntax allows setter function to get called, which retains the object once. So the actual window object which we alloced using [UIWindow alloc]
should be released, hence autorelease
. The retain using self.
syntax is conceptually released in dealloc. So for one alloc plus one retain we are releasing twice.
Where does _window come from? Is this just another way to access
[self window]
.
Well this question is already discussed here
Upvotes: 0
Reputation: 69499
In you second example you are leaking the window object since, the alloc
will give the object a retain count of 1, the you assign it _window
via the property which will also retain the object assigned to it.
It's true you should not release an autorelease object, but in the dealloc you are releasing the iVar for the window
property. You should always release any property that is declared as either retain or strong. (although not when using ARC).
The _window
is now automatically generated as the iVar for the property window
.
There some believes that you should not use self.
properties in init
or dealloc
.
Thus the way I do it is:
[_window release], _window = nil;
This wil set the _window
to nil after releasing it, making sure that if any other thread might want to use this it will be calling on nil
. Which could prevent a crash but could alo create some weird behavior. This is totally up to you.
You should move to ARC, which is a complier option to add release/autolease at compiletime fro you. There is no need to added these your self if you set the property correctly when using ARC.
Upvotes: 2
Reputation: 340
Check what the window
property memory descriptor is like. I assume it's strong
/retain
in which case when you set the window
property, it's value is retained thus needs to be released in dealloc
.
Following your code path.
[UIWindow alloc]
= retainCount of 1.dealloc
you release it, thus retainCount = 0 and the object is deletedYou probably missed out that in later iOS SDKs, auto synthesized properties automatically create instance variables with underscore prefixes. So you could also do self.window = nil
in your dealloc
.
Upvotes: 0
Reputation: 35318
So I figured this out (mostly). The @property
declaration has the strong
attribute. Apparently this is new to ARC (which I'm not actually using) and is otherwise just an alias for retain
, so self.window = [ ... ]
retains the object, hence the autorelease.
Still not clear on the _window
variable, but I assume it is just a shortcut.
Upvotes: 0