If -setName: immediately releasees the value that -name returned, oldName will be invalid when it’s used in NSLog. But if the implementation of [x name] used retain/autorelease, then oldName would still be valid, because it would not be destroyed until the autorelease pool around the NSLog was drained.

Also, autorelease pools are per thread; different threads have different autorelease pools that are drained at different times. retain/autorelease makes sure the object is on the calling thread’s pool.

Ugly

return [[x retain] autorelease]; is more complicated, and harder to understand then a simple return x;. But sometimes that ugliness is necessary, and the best place to hide it is in a one-line getter method. It’s self documenting. And once you understand Cocoa memory management, it’s entirely clear what the method does. For me, the tiny readability cost is worth the safety guarantee.

Big

return [[x retain] autorelease]; increases peak memory pressure, because it can defer dealloc-ing unused objects until a few autorelease pools are drained. Honestly I’ve never measured memory usage, and found this to be a significant problem. It certainly could be, especially if the thing being returned is a large picture or chunk of data. But in my experience, it’s nothing to worry about for getters that return typical objects, unless there are measurements saying otherwise.

Slow

return [[x retain] autorelease]; is obviously slower then just return x;. But I doubt that optimizing an O(1) getter is going to make a significant difference to your application’s performance — especially compared to other things you could spend that time optimizing. So until I have data telling me otherwise, I don’t worry about adding an the extra method calls.

This is a Good Rule to Break

As I mentioned before, getters don’t need to worry about memory management. It could be argued that the return [[x retain] autorelease]; pattern is a premature optimization of theoretical safety at the expense of concrete performance.

Good programmers try to avoid premature optimization; so perhaps I’m wrong to follow this “safer” pattern. But until I have data showing otherwise, I like to do the safest thing.

I do not prefer that style, because it’s doing extra memory management that’s irrelevant to what the code is actually doing (renaming someone “Alice”). That means more for me to puzzel through when I’m trying to figure out what’s going on.

I’d rather have a getter or setter that can’t let the problem happen. (Using autorelease in your setter works if there’s only one thread).

If I were not relying on my setter being clever, (and there are good arguments for doing that) I would do NSString *oldName = [[[person name] retain] autorelease]; instead of calling release when I’m done with oldName. That way I don’t have to think about when it’s the right time to release oldName, and more importantly I can’t do it at the wrong time, (and I can’t come back and change the code later in such a way that it becomes the wrong time).

While I do agree that you can’t do it at the wrong time, I don’t think it is more of a hassle to figure out when a good time is to release it(when you are done with the variable), nor do I think NSString* oldName = [[person name] retain]; is more irrelevant to what the code is doing than return [[x retain] autorelease]

nor do I think NSString* oldName = [[person name] retain]; is more irrelevant to what the code is doing than return [[x retain] autorelease]

Yes, the memory management is irrelevant in both cases, but

return [[x retain] autorelease] only happens in exactly one spot.

That one spot is a one-line getter method. There’s not a lot of code that it confuses.

It’s use follows a pattern, so you don’t have to think about it when you see it. (Any time you see a naked retain without some pattern justifying it, you have to figure out why — or if it’s a memory leak).

While I do agree that you can’t do it at the wrong time, I don’t think it is more of a hassle to figure out when a good time is to release it(when you are done with the variable)

That’s infinitely more work then not having to decide when you are done with something. And having to decide if you are still done with something there, every time you modify the code. And having to fix the bugs that Murphy’s Law says will happen.

Yes, in a 4 line example it’s not hard to balance retain/release; and it’s not hard much of the time. But manually malloc()/free()-ing memory isn’t hard in a 4 line example, or always difficult. But there are simpler ways, and I think it’s making life unnecessarily difficult not to use them when possible.

My spouse and I stumbled over here from a different page and
thought I may as well check things out. I like what I see so
now i’m following you. Look forward to finding out about
your web page yet again.

Wonderful blog you have here but I was curious if you knew of any community forums
that cover the same topics discussed here? I’d really love
to be a part of group where I can get opinions from other experienced people that share the same interest.
If you have any suggestions, please let me know.
Thank you!

Hello There. I discovered your blog the use
of msn. That is a really neatly written article. I will be sure to bookmark it
and come back to learn more of your helpful information. Thanks for the
post. I’ll certainly comeback.