Thanks
Thanks

Reputation: 40339

Why do I have to call super -dealloc last, and not first?

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?

Upvotes: 30

Views: 18063

Answers (6)

cocoafan
cocoafan

Reputation: 4894

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]. It is always safe to call the superclass in the last line.

Also KVO and depended (triggered) keys can produce side effects if they are depended of already released member variables.

Upvotes: 55

user387896
user387896

Reputation: 11

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

Upvotes: 1

Simo Salminen
Simo Salminen

Reputation: 2306

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!
}

Upvotes: 2

kareman
kareman

Reputation: 691

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.

Upvotes: 1

Terry Wilcox
Terry Wilcox

Reputation: 9040

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

Upvotes: 5

n3rd
n3rd

Reputation: 6089

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.

Upvotes: 12

Related Questions