0

This is a follow on from another question, my question is regarding the use of the retain/release in main(). From my understanding in this simple example the retain/release statements are not needed. BUT in more complex situations its best practice to add them as it ensures that the planet instance is not released unexpectedly.

+(Planet *) planet {
    gPlanetCount++;
    //return [[[Planet alloc] init] autorelease];
    return [[[self alloc] init] autorelease];     // Better
}

int main(int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Planet *outerMost;

    outerMost = [[Planet planet] retain];
    ...
    ... some code
    ...
    [outerMost release]; 
    [pool drain];
    return 0;
}

EDIT_001

So I could better write the above as.

int main(int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    Planet *outerMost;

    outerMost = [Planet planet];
    ...
    ... some code
    ...
    [pool drain];
    return 0;
}

cheers gary

6
  • 1
    The memory management code appears to be correct, but you might want to add NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; as the first line of your main function. You probably only forgot to leave this in your snippet as you drain the pool at the end. Commented Nov 16, 2009 at 9:00
  • Markus, I will add that right now for correctness, I have it in my code I just forgot to add it here, thanks for pointing that out. Commented Nov 16, 2009 at 10:28
  • I've never seen the use of [self alloc] in a class-level method. Does this work? I thought "self" was reserved for instances of classes. Commented Nov 16, 2009 at 10:39
  • And yes, your edit is better. Commented Nov 16, 2009 at 10:41
  • 1
    @Rein, apparently the Apple preferred way to alloc within a class method is to use "id newInstance = [[self alloc] init]; // EXCELLENT" where as "id newInstance = [[Rectangle alloc] init]; // GOOD" incase the class is subclassed. I will update my question for future reference ... Commented Nov 16, 2009 at 15:19

1 Answer 1

3

Markus Müller's comment is correct, that is, your code is correct, except for the missing pool allocation and initialization.

However, if you create an autoreleased object in a routine/method, and you use that object in that routine/method, and you are done with it, before you exit that routine/method, then there is no reason to retain it and then release it. That object is guaranteed to be retained for the duration of the life of the routine/method, and, in this case, it will most likely be released by the [pool drain] method.

You are not going to have a situation where outerMost is released unexpectedly. The expected release is in [pool drain]. It doesn't matter how many other methods are called from within main(), as long as you are sicking to the retain/release guidelines, outerMost will not need to be retained.

Sign up to request clarification or add additional context in comments.

2 Comments

Ah I see, so would you consider EDIT_001 to be a better way to write this?
fuzzygoat: Yes, since you're not unnecessarily retaining and releasing the object. As long as you don't do extremely funky things with other autorelease pools, the autorelease will not come due until you drain the pool you created in main.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.