views:

159

answers:

5

I'm new to memory-management, and am reading different things about how to best release properties.

If I have:
in .h:
@property(retain) NSString *myStr;

and in .m:
@synthesize myStr = _iVarStr;

Should my dealloc have:
[_iVarStr release];
or
self.myStr = nil;
or something else?

Thanks!

A: 

Your dealloc should be this:

- (void)dealloc {
  [_iVarStr release];
  [super dealloc];
}

Although setting the property to nil is possible, I worry about unintended side effects or KVO actions triggered by the change that may not realize the object is currently being deallocated.

Jess Bowers
Please explain why that is asking for trouble.
St3fan
Example indicating why you should use property setters in `dealloc`: http://stackoverflow.com/questions/192721#192852
Dave DeLong
Never say never. Sometimes, setting properties in a dealloc makes sense (especially when the setter has some important side effect, such as setting up an observer).
D Carney
Yes, please explain more. regarding memory management, if you evaluate _iVarStr != nil after the release, it returns false. That is not so with self.myStr = nil.
mkraken
If your setter had a lot of side effects you should not have used a property to begin with. Any side effect the setter has can only be bad, after all you are setting the "new value" to nil and about to release the whole object. The real trouble is that the setter change could fire off a KVC notification to some observer who would then try to act on an object mostly or partly deallocated. If you have a notification set up then you need to explicitly remove yourself as an observer in dealloc and not rely on side effects to do that for you.
Kendall Helmstetter Gelner
Can you explain why?
DenNukem
All good points --- I retract the "never" since that does not cover all cases.... editing it to add some of these points.
Jess Bowers
In the case of needing to clean up the object (remove observers, etc), I tend to think that logic should go before the release statements.
Jess Bowers
A: 

I recommend you use self.ivar=nil(the code ivar=nil previously I wrote was wrong) way in dealloc method. Because, if the ivar's property change from retain to assign (or from assign to retain), you don't have to change your code.

KatokichiSoft
If your ivars are `assign`, then you have to be extra careful that your objects aren't deallocated from underneath you.
Dave DeLong
This doesn't make sense to me because just setting the internal ivar to nil does not release it - that makes sense for an assign property but not retain.
Kendall Helmstetter Gelner
Sorry, I made a mistake. The exact way is `self.ivar=nil`. only `ivar=nil` is bad.
KatokichiSoft
A: 

When a property is set to retain then

self.ivar = nil;

will properly manage the memory allocation. For other property types check the at the official documentation page. It also has a bunch of sample code so you can understand what happens "under the hood" for all the options.

Dustin Pfannenstiel
Do you mean self.myStr = nil?
mkraken
Yes. The code listed in Saurabh's answer is pretty close to the synthesized transformer.
Dustin Pfannenstiel
+2  A: 

I would recommend reading this thread:

http://stackoverflow.com/questions/1458178/iphone-dealloc-release-vs-nil/2371133#2371133

Remover
Thanks - that's a great read.
mkraken
A: 

Both self.myStr = nil and [myStr release] ultimately do the same thing.

Calling [myStr release] is obvious and just releases it.

Meanwhile, the setter method for myStr looks roughly like this:

- (void)setMyStr:(NSString *)newMyStr
{
    [newMyStr retain];
    [myStr release];
    myStr = newMyStr;
}

So when we do self.myStr = nil, we're first retaining a nil object, which does nothing. Then we release the old variable, which is what we want. Finally, we set the pointer to nil.

What's the difference? The latter sets the pointer to nil. This is better because if we (accidentally) send a message to the released object, we crash if the pointer isn't nil (EXC_BAD_ACCESS). Now honestly, since you're in -dealloc, the object is being destroyed anyways, so it wouldn't really matter what you use.

mkraken