Vincent Gable’s Blog

March 31, 2009

How To Write Cocoa Object Getters

Setters are more straightforward than getters, because you don’t need to worry about memory management.

The best practice is to let the compiler write getters for you, by using Declared Properties.

But when I have to implement a getter manually, I prefer the (to my knowledge) safest pattern,

- (TypeOfX*) x;
{
  return [[x retain] autorelease];
}

Note that by convention in Objective-C, a getter for the variable jabberwocky is simply called jabberwocky, not getJabberwocky.

Why retain Then autorelease

Basically return [[x retain] autorelease]; guarantees that what the getter returns will be valid for as long as any local objects in the code that called the the getter.

Consider,

NSString* oldName = [person name];
[person setName:@"Alice"];
NSLog(@"%@ has changed their name to Alice", oldName);

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.

If this cursory explanation isn’t enough, read Seth Willitis’ detailed explanation of retain/autorelease. I’m not going to explain it further here, because he’s done such a through job of it.

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.

How do you write getters, and why?

13 Comments »

  1. Wouldn’t the following code be considered better:
    NSString* oldName = [[person name] retain];
    [person setName:@”Alice”];
    NSLog(@”%@ has changed their name to Alice”, oldName);
    [oldName release];

    Comment by GaViT — April 17, 2009 @ 3:38 pm

  2. @GaViT,

    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).

    Comment by Vincent Gable — April 17, 2009 @ 5:12 pm

  3. 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]

    Comment by GaViT — April 18, 2009 @ 9:50 am

  4. 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

    1. return [[x retain] autorelease] only happens in exactly one spot.
    2. That one spot is a one-line getter method. There’s not a lot of code that it confuses.
    3. 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).

    Comment by Vincent Gable — April 18, 2009 @ 5:16 pm

  5. 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.

    Comment by Vincent Gable — April 18, 2009 @ 5:35 pm

  6. I use @synthesize and let Apple do it the best way possible, given context.

    If in a non-GC’d environment, specifying an @property as nonatomic just returns the underlying object value.

    Comment by bbum — May 18, 2009 @ 1:14 am

  7. Shouldn’t your article begin with “Getters are more straightforward than setters”, instead of “Setters are more straightforward than getters, because you don’t need to worry about memory management.

    Comment by Ricky Helgesson — April 27, 2012 @ 3:14 am

  8. Hi guys and gals ! How are you ? I am new here, pleaze welcome me.

    Comment by felteklyKal — June 4, 2013 @ 9:34 pm

  9. Link exchange is nothing else but it is just placing the other persons weblog link on your page at proper place and other person will also do similar in support of you. edfckddaddffeebe

    Comment by Smithe0 — May 13, 2014 @ 11:30 pm

  10. Nice weblog right here! Also your site so much up fast!
    What web host are you the usage of? Can I get your
    affiliate hyperlink to your host? I want my website loaded up as fast as
    yours lol

    Feel free to visit my blog: acne product reviews over the counter

    Comment by acne product reviews over the counter — May 20, 2014 @ 5:06 am

  11. 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.

    Check out my web-site :: mind control power attracting women – Inge,

    Comment by Inge — July 9, 2014 @ 11:54 am

  12. 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!

    Comment by prix dj Magog — February 5, 2015 @ 2:23 pm

  13. 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.

    Comment by nex 3c nex — May 11, 2015 @ 3:02 am

RSS feed for comments on this post.

Leave a comment

Powered by WordPress