Утечка памяти при использовании 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
}
когда я изменил код на это:
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)
}
}
1 ответ
Проблема заключается в строковом литерале ("предложение") в вызове метода totableView.dequeueReusableCell.
Из яблочных документов на строки:
Вы можете создавать новые строки, используя строковые литералы или интерполяции строк. Строковый литерал - это серия символов, заключенная в кавычки.
А также
Хотя строки в Swift имеют семантику значений, строки используют стратегию копирования при записи для хранения своих данных в буфере. Этот буфер может затем совместно использоваться различными копиями строки. Данные строки копируются только лениво после мутации, когда более одного экземпляра строки используют один и тот же буфер.
Я считаю, что вы выделяете 48 байтов каждый раз, когда вызывается метод с созданием строкового литерала. Я думаю, что компилятор должен оптимизировать это, но я не уверен.
Если ваш инициализатор CodeOfConductTableViewCell() загружает ресурс из XCode, он будет иметь дополнительные затраты на чтение XIB, что может объяснить различия в производительности, которые вы видите.
Вы должны сделать свой идентификатор константой в модуле и посмотреть, исчезнет ли утечка, поскольку компилятор выделит его только один раз.