correct example:
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
wrong example:
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.
[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.
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!
}
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.
[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.
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.