0

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!

DShah
  • 9,768
  • 11
  • 71
  • 127
Kreegr
  • 149
  • 10
  • 1
    On a related note, try to use the 'nonatomic' property wherever possible. According to Apple, it can result in significant performance improvements (at the cost of some risk if you get into multi-threaded programming). – David Carney Mar 19 '10 at 16:54
  • Is it possible that the answer will depend on how the setters and getters are implemented/synthesized? – Kreegr Mar 19 '10 at 17:04
  • Yes - good note. nonatomic was omitted for brevity. – Kreegr Mar 19 '10 at 17:06
  • I would recommend reading this thread: http://stackoverflow.com/questions/1458178/iphone-dealloc-release-vs-nil/2371133#2371133 – Remover Mar 19 '10 at 16:54
  • Thanks - that's a great read. – Kreegr Mar 19 '10 at 17:39

4 Answers4

1

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.

  • This answers my original question for synthesized setters & getters. It is clear to me though, that for custom setters or different property attributes the answer may vary. Remover's response was also very helpful - http://stackoverflow.com/questions/1458178/iphone-dealloc-release-vs-nil/2371133#2371133 Thanks for responses! – Kreegr Mar 19 '10 at 17:42
0

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
  • 2,846
  • 1
  • 22
  • 42
  • Please explain why that is asking for trouble. – Stefan Arentz Mar 19 '10 at 16:06
  • Example indicating why you should use property setters in `dealloc`: http://stackoverflow.com/questions/192721#192852 – Dave DeLong Mar 19 '10 at 16:15
  • 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). – David Carney Mar 19 '10 at 16:51
  • 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. – Kreegr Mar 19 '10 at 16:55
  • 1
    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 Mar 19 '10 at 17:25
  • All good points --- I retract the "never" since that does not cover all cases.... editing it to add some of these points. – Jess Bowers Mar 19 '10 at 17:52
  • 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 Mar 19 '10 at 17:58
0

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
  • 932
  • 5
  • 8
0

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.