Object leak using "retain"
I have a property defined with retain attribute which I am synthesizing:
@property (nonatomic, retain) UISwitch *mySwitch;
And inside my loadView I am doing this:
self.mySwitch = [[UISwitch alloc] initWit开发者_如何学JAVAhFrame:CGRectMake(0, 0, 40, 20)];
And finally inside my dealloc I am doing this:
self.mySwitch = nil;
Am I leaking this object (mySwitch) as I have used one alloc? Should I autorelease it while assigning it frame?
Please suggest.
The line:
self.mySwitch = [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
Actually calls retain twice- once for the alloc
and again in the assignment to self.mySwitch
(which is a property you've specified should retain
any values assigned to it.) The fix I have been told is best is to add a call to autorelease
on the line, making it:
self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];
Yes, you are leaking. You are creating an owned object with +alloc/-initWithFrame:
, then assigning that owned object to a property marked retain
. This creates a second owned reference to the object. At this point, you leak your original owned reference, which causes the object itself to leak.
The correct behavior here is to call -autorelease
on the object before assigning it to the property.
self.mySwitch = [[[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)] autorelease];
On a tangential note, it's not recommended that you access properties inside of -dealloc
. The two reasons generally given for this are 1) this will broadcast KVO notifications, which you don't want inside of -dealloc
, and 2) if anyone overrides the setter (in this class or a subclass) it may not behave properly. The recommended approach is to simply release the underlying ivar, so you'd see something like the following instead:
[mySwitch release];
Assigning nil to the property is perfectly safe (and recommended) everywhere else.
As alternative to autorelease, if you need a tighter memory management this should work for you:
UISwitch *myswitch_tmp= [[UISwitch alloc] initWithFrame:CGRectMake(0, 0, 40, 20)];
self.mySwitch = myswitch_tmp;
[myswitch_tmp release];
and later e.g. in dealloc
[mySwitch release];
Yes. You are leaking object. Remember one simple rule here:
if you used +alloc
there is always must be corresponding -release
.
精彩评论