Цикл сильных ссылок UITableViewCell, но его не улавливают утечки в инструментах - PullRequest
2 голосов
/ 02 августа 2020

Я заполняю UITableView пользовательскими ячейками UITableViewCell, в каждом из которых есть кнопка. Чтобы проверить, нажата ли кнопка, я использую шаблон протокола делегата. Вот моя реализация:

protocol MyTableViewCellDelegate {
    func didPressButtonInTableView(for indexPath: IndexPath)
}

class MyTableViewCell: UITableViewCell {

    lazy var indexPath = (self.superview?.superview as! UITableView).indexPath(for: self)
    var delegate: MyTableViewCellDelegate!

    @IBAction func buttonPressed(_ sender: Any) {
        self.delegate.didPressButtonInTableView(for: self.indexPath!)
    }

}

Прочитав немного об управлении памятью, я понял, что иногда экземпляры дочернего класса, содержащие ссылки на родительский класс, не освобождаются из-за «цикла сильных ссылок» , поскольку и родительский класс, и дочерний класс имеют сильную ссылку друг на друга. Мы должны использовать ключевое слово weak, чтобы определить слабую связь, по которой, когда родительский класс освобождается, дочерний класс тоже.

Итак, я понял, что использование делегата содержит сильную ссылку на UITableView (родительский класс). Выполнив некоторые тесты, такие как проверка использования памяти в отладчике Xcode и использование deinit в дочернем классе, я понял, что эти ячейки представления таблицы не освобождаются. Изменение протокола на использование AnyObject, а затем установка делегата как weak устранили проблему. При повторном запуске использование памяти не увеличивалось, и когда я перешел в другое представление, было вызвано deinit.

При запуске обеих версий кода в Leaks in Instruments утечек памяти в первом случае не было. однако при каждой загрузке табличного представления происходило очень заметное увеличение памяти.

Мой вопрос: почему это не помечено как утечка памяти в инструментах, поскольку дочерний класс имеет сильную ссылка на родительский класс с помощью делегата? В чем разница между этой ссылкой и традиционной ссылкой родительско-дочерней строки, которая вызывает утечки, обнаруженные инструментами?

1 Ответ

0 голосов
/ 03 августа 2020

Это потому, что tableView повторно использует ячейку. Поскольку ячейки tableview используются повторно, они, как правило, деиницируются только в том случае, если деиницируется само tableview. Потому что, даже если они не используются прямо сейчас, tableview сохранит их живыми на случай, если они понадобятся для повторного использования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...