Почему я должен вызывать super -dealloc последним, а не первым?

Если вы используете Guava ( https://code.google.com/p/guava-libraries/ ), у вас будет этот сахарный код:

private ArrayList list = Lists.newArrayList("element1", "element2", ...)

Кроме того, было упомянуто ранее, я предлагаю не печатать ваше поле как ArrayList, а как List. Всегда используйте более абстрактный тип, правильное правило большого пальца.

29
задан Thanks 26 May 2009 в 09:44
поделиться

6 ответов

Это всего лишь рекомендация. Вы можете вызывать другие инструкции после [super dealloc] . однако вы больше не можете получить доступ к переменным суперкласса, потому что они освобождаются, когда вы вызываете [super dealloc] . Всегда безопасно вызывать суперкласс в последней строке.

Также KVO и зависимые (запускаемые) ключи могут вызывать побочные эффекты, если они зависят от уже выпущенных переменных-членов.

однако вы больше не можете получить доступ к переменным суперкласса, потому что они освобождаются, когда вы вызываете [super dealloc] . Всегда безопасно вызывать суперкласс в последней строке.

Также KVO и зависимые (запускаемые) ключи могут вызывать побочные эффекты, если они зависят от уже выпущенных переменных-членов.

однако вы больше не можете получить доступ к переменным суперкласса, потому что они освобождаются, когда вы вызываете [super dealloc] . Всегда безопасно вызывать суперкласс в последней строке.

Также KVO и зависимые (запускаемые) ключи могут вызывать побочные эффекты, если они зависят от уже выпущенных переменных-членов.

54
ответ дан 28 November 2019 в 01:03
поделиться

[super dealloc] освобождает память, используемую вашим объектом, включая указатели на viewController и window. Ссылаться на переменные после того, как вы их освободили, в лучшем случае опасно.

См. этот ответ .

5
ответ дан 28 November 2019 в 01:03
поделиться

Я ничего не знаю о программировании для iPhone, но предполагаю что по той же причине деструкторы нужно вызывать в обратном порядке. Перед вызовом суперкласса вы хотите убедиться, что весь ваш «мусор» очищен. Если вы сделаете наоборот, все может запутаться. Например,

12
ответ дан 28 November 2019 в 01:03
поделиться

Практически у вас почти [super dealloc] в конце, потому что он освобождает переменные суперкласса, и к ним больше нельзя получить доступ.

Одно исключение - если у вас есть подкласс UITableViewController, который использует другой класс в качестве делегата табличного представления. В этом случае вы должны освободить делегата табличного представления после [super dealloc] , потому что табличное представление ссылается на делегата табличного представления, а табличное представление должно быть освобождено первым.

1
ответ дан 28 November 2019 в 01:03
поделиться

Вот реальный пример, где [super dealloc] должен быть последним, иначе вызов removeFromRunLoop вызовет сбой. Я не уверен, что происходит внутри NSOutputStream removeFromRunLoop, но в этом случае он, похоже, обращается к «себе».

Настройка:

[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!
}
2
ответ дан 28 November 2019 в 01:03
поделиться

[к последнему сообщению] Разве tableView, ссылающийся на делегата, не отвечает за освобождение собственного делегата? Я бы подумал, что он сохранил его при установке (чтобы вы могли освободить или автоматически выпустить его), и он сам позаботится о себе?

Что касается вопроса OP, я всегда буду сначала вызывать super, если я создаю, и называть super last, если Я разрушаю. Я думаю об этом так: «Я хочу, чтобы супер билд был таким, какой он хочет, чтобы я мог на этом опираться, и я хочу, чтобы супер сносили последним, после того как я уберу за собой». Практически все вызовы, которые я использую, являются конструируемыми, за исключением dealloc, поэтому вы всегда будете видеть его последним в моем коде dealloc.

1
ответ дан 28 November 2019 в 01:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: