I know that if you do the following you most certainly have a memory leak:
id foo = [[NSObject alloc] init];
foo = nil;
But, what if you're using self.foo, a property with retain? And your code instead looks like the following:
foo = [[NSObject alloc] init];
self.foo = nil;
Is that still a memory leak since the accessor releases the memory first before setting it to nil?
-
self.foo = nil
would translate into[nil retain] [foo release] foo = nil
There is no memory leak here.
-
Nope, the second example is not a memory leak. In fact, that's how I deal with
retain
properties in mydealloc
method. It's just a lot cleaner.The only thing you have to be careful about is making sure not to write
self.foo = [[NSObject alloc] init];
or else you'll double-retain the object and end up with a memory leak.
Marc Charbonneau : Keep in mind using properties in dealloc is usually discouraged in case the accessor method is changed to modify another ivar (which might have already been released). I just use release instead.e.James : @Alex: +1 for an excellent warning, but -1 for the suggestion to use self.foo = nil in a dealloc method!Jason Coco : @eJames self.foo = nil is the way Apple were recommending doing it in the dealloc method originally and is everywhere in their sample code.Alex : I think for run-of-the-mill @synthesize accessors, the property syntax is the way to go. It's good enough for Apple! My thinking is, why spend two lines doing what you could do in one?Tom Andersen : Properties in Obj-C 2 look nice, but they add complexity - especially when you can mix and match. I think they should have gone further. Maybe we will will get there in another 15 years with ObjC 3. -
I don't think so as by doing
self.foo = nil
you are essentially using the setter and getting the memory management along for free. -
Properties make it your code look like assignment, but in reality they're the same as traditional accessor methods you might have written yourself prior to Obj-C 2.0. With properties Obj-C is simply generating the accessor methods behind the scenes for you instead using the keywords you specify in the declaration (assuming you use @synthesize and don't write your own accessor methods anyway).
-
No, there is no memory leak. The code in your second example is logically equivalent to
foo = [[NSObject alloc] init]; [nil retain]; [foo release]; foo = nil;
because the @synthesized setter is logicall equivalent to
- (void)setFoo:(id)newFoo { [newFoo retain]; [foo release]; foo = newFoo; }
It's worth noting that setting
foo
directly is probably not something you want to do outside of an init method. If you assign a value tofoo
directly, you bypass the automatic KVO notification (you would have to wrap your assignment in awillChangeValueForKey:/didChangeValueForKey:
pair) and you break any subclass' behavior if it overrides thesetFoo:
method, expecting all modifications offoo
to go through the setter.You assign directly to
foo
in an init method because thesetFoo:
method or a subclass' overridensetFoo:
method may have side-effects or depend on the instance's fully initialized.Similarly, you would use
[foo release]
rather thanself.foo = nil;
in the-dealloc
method for the same reasons. -
All the answers so far assume that “
foo
” in the first line of the second example is the instance variable behind thefoo
property. This is the default behavior.If the
foo
that the first line assigns to is a local variable, then thefoo
property is irrelevant, and you will leak the object unless you release it later in the method.If
foo
is an instance variable, but thefoo
property is actually backed by a different instance variable, or no instance variable at all, then (a) you are writing hard-to-maintain code and (b) it may be a leak.Finally, echoing the previous answers: If
foo
is the instance variable backing thefoo
property, then this is not a leak, since thesetFoo:
method that you call in the second line will release the object that you put in thefoo
instance variable in the first line.
0 comments:
Post a Comment