为什么最后要调用super-dealloc,而不是先调用?
正确的例子:
- (void)dealloc { [viewController release]; [window release]; [super dealloc]; }
错误的例子:
- (void)dealloc { [super dealloc]; [viewController release]; [window release]; }
同样,在重写一个方法的时候,我会首先调用super的方法实现,在这种情况下,苹果总是调用[super dealloc]。 为什么?
它只是一个准则。 您可以在[super dealloc]
之后调用其他指令。 但是你不能访问超类的variables,因为当你调用[super dealloc]
时候它们被释放了。 在最后一行中调用超类总是安全的。
另外KVO和depended(触发)键可以产生副作用,如果他们依赖已经释放的成员variables。
我对iPhone的编程知之甚less,但我认为这是出于同样的原因,需要以相反的顺序调用析构函数。 你要确保在调用你的超类之前清理所有的“垃圾”。 如果你这样做,相反的事情可能会变得混乱。 例如,如果你的析构函数需要访问超级析构函数已经释放的内存:
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(); } } }
你可能不会在你的代码中遇到这个问题,因为“你知道你在做什么”,但是不做这样的事情是一个更安全和整体更好的做法。
[super dealloc]释放你的对象使用的内存,包括指向viewController和窗口的指针。 在释放之后引用variables是最好的。
看到这个答案 。
这里是[super dealloc]必须是最后一个的实际例子,否则调用removeFromRunLoop将导致崩溃。 我不知道在NSOutputStream的removeFromRunLoop里面会发生什么,但是在这种情况下它似乎访问了“self”。
build立:
[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! }
实际上,在最后几乎都有[super dealloc]
,因为它释放了超类的variables,不能再被访问。
一个例外是,如果你有一个UITableViewController的子类,使用另一个类作为它的表视图委托。 在这种情况下,您必须在[super dealloc]
之后释放表视图委托,因为表视图引用了表视图委托,并且必须首先释放表视图。
[到最后一篇文章]不会引用委托的tableView负责释放它自己的委托? 我认为它会在设置时保留下来(所以你可以释放或自动释放它),它会自行处理?
至于OP的问题,如果我正在构build,我会一直叫超级,如果我正在破坏,我会叫超级。 我认为这是因为“我想要超级build立自己想要的东西,所以我可以build立在这个基础上,而且在我自己清理完之后,我希望超级能够继续推下去”。 几乎所有的调用都在构build,除了dealloc,所以这就是为什么你总是会看到它在我的dealloc代码中的最后一个。