views:

2252

answers:

6

correct example:

- (void)dealloc {
    [viewController release];
    [window release];
    [super dealloc];
}

wrong example:

- (void)dealloc {
    [super dealloc];
    [viewController release];
    [window release];
}

Althoug in alsmost all other cases when overriding a method I would first call the super's method implementation, in this case apple always calls [super dealloc] in the end. Why?

+5  A: 

I don't know anything about programming for the iPhone, but I would assume that it is for the same reason that destructors need to be called in reverse order. You want to make sure that all your 'garbage' is cleaned up before calling your superclass. If you do it the other way around things can get messy. For instance, if your destructor needs to access memory that the super destructor has already freed:

class X {
    private Map foo;

    function __construct() {
        foo = new Map();
    }

    function __destruct() {
        foo.free;
    }
}

class Y extends X {
    function __construct() {
        super.__construct();
        map.put("foo", 42);
    }

    function __destruct() {
        super.__destruct();
        if (map.containsKey("foo")) {    // boooooooooom!
            doSomething();
        }
    }
}

You may not encounter this problem in your code, because "you know what you're doing", but it is a safer and overall better practice not to do such things.

n3rd
Anyone care to elaborate why this was downvoted?
n3rd
Anyone care to elaborate why this was upvoted?
Joe Philllips
My guess is because it answered the question, at least partially. A downvote on the other hand commonly implies that the answer was unhelpful or just plain wrong. If it was wrong I would very much like to know why so I can learn from my mistake. Or were you just being polemic?
n3rd
I didn't downvote it; it's a good answer. However, the downvote is fair enough since it's a guess, not specific to the Cocoa framework.
Adam Ernst
+9  A: 

Its just a guideline. You can call other instructions after [super dealloc]. however you can not access variables of the superclass anymore because they are released when you call [super dealloc]. Its always safe to call the superclass in the last line.

Also KVO and depended (triggered) keys can affect side effects if they are depended of already release member varibles.

cocoafan
+2  A: 

[super dealloc] is freeing up the memory used by your object, including the pointers to viewController and window. Referring to variables after you've freed them is hazardous at best.

See this answer.

Terry Wilcox
A: 

You practically almost have [super dealloc] at the end because it frees up the variables of the superclass and they can no longer be accessed.

One exception is if you have a subclass of UITableViewController that is using another class as its table view delegate. In that case you have to release the table view delegate after [super dealloc] because the table view is referencing the table view delegate and the table view has to be released first.

Kare Morstol
Can you give a little more detail of your exception? It sounds slightly wrong to me.
Mark Bessey
+1  A: 

Here is actual example where [super dealloc] must be last, otherwise the call to removeFromRunLoop will cause crash. I'm not sure what happens inside NSOutputStream's removeFromRunLoop, but it seems to access 'self' in this case.

Setup:

[outputStream setDelegate:self];
[outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];

Dealloc:

- (void)dealloc {
    if (outputStream) {
        [outputStream close];
        [outputStream removeFromRunLoop:[NSRunLoop currentRunLoop]
                                forMode:NSDefaultRunLoopMode];
        [outputStream release];
        outputStream = nil;
    }
    delegate = nil;
    [super dealloc]; // must be last!
}
Simo Salminen
A: 

[to the last post] Wouldn't the tableView referencing the delegate be responsible for releasing it's own delegate? I would think it's retained it when set (so you could release or autorelease it) and it would take care of itself?

As for the OP question, I will always call super first if I'm constructing and call super last if I'm destructing. I think of it as "I want to have super build what it wants so I can build on that, and I want super to tear down last after I clean up after myself." Virtually all the calls I use are constructing though, except dealloc, so that's why you would see it last in my dealloc code always.