Subscribe to
Posts
Comments
NSLog(); Header Image

Accessor Methods

Not to start a holy war, but I came face to face with one of those little things about which some people get pretty uptight. While looking through the CURLHandle example, I found that Dan Wood had implemented his setter accessor method in this way:

- (void)setThing:(id)newThing
{
    [newThing retain];
    [thing release];
    thing = newThing;
}


I'm not too fond of that one, personally. I typically write my accessor methods like this:

- (void)setThing:(id)newThing
{
    id old = thing;
    thing = [newThing retain];
    [old release];
}

I like to save the release for the last. Some people like to go this route, and I'm trying to do this more lately:

- (void)setThing:(id)newThing
{
    if (newThing != thing)
    {
        [thing release];
        thing = [newThing retain];
    }
}

Need another way?

- (void)setThing:(id)newThing
{
    [thing autorelease];
    thing = [newThing retain];
}

I won't discuss the pros and cons of either. But there you go: a bunch of ways to write setter accessor methods in Objective-C.

19 Responses to "Accessor Methods"

  1. Hey, I resemble that entry! 🙂

    Why did I use the technique above (retain/release/assign)? Hmm, I learned it somewhere as the right thing to do, and now I have a Completion Dictionary macro for it. The idea is that it will work if newThing is the same as thing.

    The second one seems functionally equivalent, though personally I don't find it as easy to follow what it's doing. The third way may not be a good idea in a tight loop because it adds an item to the autorelease pool each time.

  2. I think you meant the fourth… which makes me wonder what you mean by second? 🙂

  3. I learned early on that the first was 'correct' and acceptable in cases where it doesn't need robust thread-safety. Of course, I'm an amateur programmer, so I can't comment for sure.

    The second doesn't seem very clear to me, maybe just because I'm not used to seeing it.

    The third is clear and seems effective. It looks like it would be more efficient in cases where you are expecting thing and newThing to be the same frequently, because you save yourself from having to make a useless retain and release. But in cases where thing and newThing are almost always going to be different, then you lose out because you still need to retain and release, but you also have an extra if to process.

    The fourth seems like not a great idea, simply because of the addition of objects to the autorelease pool, when you probably don't need to create them. But there may be advantages I don't understand yet.

    I don't know of any real 'problems' with any of them, but the various benefits aren't that clear to me. It would be nice if you could give a little 'readers digest' version of why you prefer the ones you prefer, for those of us who are new to the whole thing.

    Peace,

    Sam

  4. The accessors in "Cocoa Programming for Mac OS X" by Aaron Hilegass are written just like Mr. Wood writes them.

  5. Just track the retain counts. They're all fairly equal. The one with the if test is, indeed, useful for objects where they're the same. Tests (if) are much faster than a retain/release, which has to do a dictionary lookup (it's not just a counter increment/decrement).

  6. you can in fact just do a [thing release] without checking if thing is nil. since 10.2 (at least) you can send release messages to nil without any adverse effects (but only to nil, not garbage data)

  7. At WWDC last year, Ali Ozer gave a talk on using Cocoa properly. One of the bits of that talk was how to write accessors (both setters and getters) and the implications and tradeoffs of the different approaches. If you have an ADC membership and can get to the WWDC 2002 video (or own the DVD's), watch Session 302 Cocoa API Techniques.

  8. For those who are wondering, the talk is on DVD 3. I'll post a summary of what Ali says when I get the chance tomorrow.

  9. The Cocoa Bible ("Cocoa Programming" by Anguish, Buck, Yacktman) also uses Mr. Wood's style. It does so because this implementation can handle all three of the following cases, in which newThing can be:

    - nil

    - a different object than the existing object

    - an object identical to the existing object

    An it works without testing for nil, testing for equality, etc. It may not be the fastest implementation, but the clearest.

  10. Thomas, be fair. The second method handles all three as well. So does the third. And the fourth. Obviously some test, but a test is very, very fast. It's a pointer comparison - very quick. You can probably run a hundred pointer comparisons in the time it takes you to retain and autorelease something.

  11. Okay, dumb question for ya all (especially Erik, since it's his blog, but the rest of you too):

    I haven't programmed in C since, oh gads, the dark ages of 1987 or so. I am fairly up on the concept of OO in theory, although I've never programmed in C++. (Most of my programming in the last 10 years or so has been in Perl.)

    Where should I start learning/relearning Objective C? I want to get into programming on Mac OS X, so I'd appreciate pointers.

    Feel free to write this up as a separate post on your blog and zap me the address, if you're going to make a long write-up of it. I'm sure I'm not the only one asking these kinds of questions. 🙂 [Also feel free to ignore me completely!]

    --Kynn

  12. Aren't accessor methods a constant pain. You'll have to add them (not to mention the redundant header information), you'll have to change them when changing a variable name. There are 'bad' ways of doing it, like the autorelease example above.

    Why doesn't the IDE simply and transparently generate them for you?

    Doesn't sound like it should be a technical problem.

  13. ssp: As a later post of mine (I'll TrackBack this article) will illustrate, it's good that we still write accessors because the differences between two different ways of writing them have impact: performance, memory, threading, etc. There is no "one size fits all" solution.

    Kynn: read Apple's "The Objective-C Programming Language" and look at tutorials online (http://cocoadevcentral.com/ is a good place to start).

  14. I am sure there is a way that fits most 🙂

    I am equally sure that programmers - being the smart people that they are - could come up with a way where you'd still be able to have your own accessor methods override the default ones.

    But I'm the one who dreams of garbage collection. I never wrote a program that would've suffered by the perfomance hit by having garbage collection either.

    I have many other questionable opinions on programming as well 😉

  15. Erik, thanks! You're a champ.

    --Kynn

  16. I wrote about accessor methods in Cocoa before. One of the comments on that article implored me to check out Ali Ozer's talk at WWDC....

  17. Jamie's written in a far better manner than I could an entry discussing the self-censorship one must apply to their blogging. She also links to...

  18. I also don't get the need for accessor methods at all. If I declare a variable in the header and set its value to someting can I not just access its value directly from another object as long as I retain it? what am I missing here...

    clarity greatly appreciated!

  19. Uh, you're missing a lot. More than I have time to discuss here. Research this on your own. The short version: you miss the ability to manage memory, do logic and bounds-checking, etc.


Trackback URI | Comments RSS

Leave a Reply

Please abide by the comment policy. Valid HTML includes: <blockquote><p>, <em>, <strong>, <ul>, <ol>, and <a href>. Please use the "Quote Me" functionality to quote comments.