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 = nilwould translate into[nil retain] [foo release] foo = nilThere is no memory leak here.
-
Nope, the second example is not a memory leak. In fact, that's how I deal with
retainproperties in mydeallocmethod. 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 = nilyou 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
foodirectly is probably not something you want to do outside of an init method. If you assign a value tofoodirectly, 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 offooto go through the setter.You assign directly to
fooin 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-deallocmethod 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 thefooproperty. This is the default behavior.If the
foothat the first line assigns to is a local variable, then thefooproperty is irrelevant, and you will leak the object unless you release it later in the method.If
foois an instance variable, but thefooproperty 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
foois the instance variable backing thefooproperty, then this is not a leak, since thesetFoo:method that you call in the second line will release the object that you put in thefooinstance variable in the first line.
0 comments:
Post a Comment