Утечка памяти при использовании UITableView dequeueReusableCell

Я проверил свое приложение на предмет утечек памяти в инструменте "Утечки". и обнаружил около 16 из них на контроллере, отвечающем за содержимое UITableView.

это код -

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: "clause", for: indexPath) as! CodeOfConductTableViewCell

    cell.index.text = String(indexPath.row + 1)
    cell.cocTxt.text = lines["line\(indexPath.row + 1)"]

    return cell
}

Утечка памяти при использовании UITableView dequeueReusableCell

когда я изменил код на это:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = CodeOfConductTableViewCell()

    cell.index = UILabel()
    cell.cocTxt = UITextView()

    cell.index?.text = String(indexPath.row + 1)
    cell.cocTxt?.text = lines["line\(indexPath.row + 1)"]

    return cell
}

утечек не обнаружено.

что вызывает утечки? я неправильно использую?

Я хочу использовать эту функцию, так как она лучше для производительности, и я хочу понять, что здесь не так

Спасибо!

Обновлено:

добавление кода класса ячейки (здесь ничего особенного):

class CodeOfConductTableViewCell: UITableViewCell {

@IBOutlet weak var index: UILabel!
@IBOutlet weak var cocTxt: UITextView!

override func awakeFromNib() {
    super.awakeFromNib()

}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)

}

}

Что вы имеете в виду под «лучше для производительности»?

Chip Coons 11.07.2018 16:43

Как вы создаете метку и текстовое представление в своей ячейке в первом примере? Переменные объявлены слабыми?

Sean Kladek 11.07.2018 16:54

@skladek да, они объявлены слабыми точками. нет специальной инициализации ..

Lerman 11.07.2018 18:20

@ChipCoons вместо создания новых ячеек эта функция повторно использует ячейки, которые находятся за кадром. если у меня очень большая таблица, приложению не хватит памяти, если я буду продолжать создавать новые ячейки.

Lerman 11.07.2018 18:26

что содержат строки?

nikBhosale 11.07.2018 19:29

@nikBhosale lines - это словарь, извлеченный из файла json. который содержит пару строк текста ...

Lerman 11.07.2018 20:42
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
1 955
1

Ответы 1

Проблема заключается в строковом литерале («предложении») в вызове метода totableView.dequeueReusableCell.

Из документов яблока на строках:

You can create new strings using string literals or string interpolations. A string literal is a series of characters enclosed in quotes.

А также

Although strings in Swift have value semantics, strings use a copy-on-write strategy to store their data in a buffer. This buffer can then be shared by different copies of a string. A string’s data is only copied lazily, upon mutation, when more than one string instance is using the same buffer.

Я считаю, что вы выделяете 48 байтов каждый раз, когда вызывается метод с созданием строкового литерала. Я бы подумал, что компилятор должен оптимизировать это, но я не уверен.

Если ваш инициализатор CodeOfConductTableViewCell () загружает ресурс из Xcode, у него будут накладные расходы на чтение xib, что может объяснить наблюдаемые вами различия в производительности.

Вы должны сделать свой идентификатор константой в модуле и посмотреть, исчезнет ли утечка, поскольку тогда компилятор выделит его только один раз.

Я сделал "предложение" статической строкой. все еще течет ... :(

Lerman 11.07.2018 20:34

Я создал простой тестовый проект с UITableView и близким приближением вашего кода (очевидно, у него нет объекта CodeOfConductTableViewCell) и не смог создать условия утечки. Я подозреваю, что в вашем классе ячейки просмотра есть что-то, что является источником утечки.

Chip Coons 12.07.2018 05:12

Я протестирую его позже, но не должны ли я получить утечки и с моим измененным примером кода? (где я явно создаю CodeOfConductTableViewCell)

Lerman 12.07.2018 15:25

Я урезал его, чтобы вернуть только удаленную ячейку без назначения каких-либо данных. все еще просачивается :( Я добавил код класса ячейки к вопросу выше. Только два выхода. Я теряю его ...

Lerman 12.07.2018 22:47

У вас есть набор тестовых данных для линий? Повторное создание кода без этой одной строки также выполняется без утечек. (т.е. закомментировал строку cell.cocTxt.text = lines ["line (indexPath.row + 1)"])

Chip Coons 19.07.2018 15:38

я закомментировал эту строку. все еще протекает .. только при замене dequeueReusableCell на создание собственных ячеек - утечек нет.

Lerman 21.07.2018 10:12

Другие вопросы по теме