Tag: «утечки памяти»
Weak delegate в Swift 3
Боролся тут с утечками памяти в рабочем проекте. Копание привело к тому, что после ухода из UIViewController далеко не вся память освобождается. Если несколько раз открывать этот UIViewController, возвращаться назад и снова открывать - потребляемая память растёт и не очень слабо освобождается.
Суть проблемы оказалась в протоколах и делегатах. У меня в UIViewController используется UICollectionView с кастомной ячейкой, у которой есть делегат. Мой UIViewController является для каждой ячейки делегатом. Пример реализации протокола и делегата в интернете и книге по Swift выгядит примерно так:
// Protocol
protocol MyCollectionViewCellDelegate {
func someFunc()
}
// UICollectionViewCell
final class MessageCollectionViewCell: UICollectionViewCell {
var delegate: MyCollectionViewCellDelegate?
}
// UIViewController
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// some code....
cell.delegate = self
}
Насколько я понял, внутри объекта ячейки получается strong-ссылка на делегата (UIViewController), в результате происходит утечка памяти.
Решение оказалось простое - чтобы сделать слабую ссылку, необходимо ограничить протокол так, чтобы ему удовлетворять мог только класс, и сделать слабую ссылку у проперти delegate. Структуры уже не смогут отвечать протоколу, но в моём случае этого и не нужно, я точно знаю, кто будет делегатом. Меняется всё так:
// Protocol
protocol MyCollectionViewCellDelegate: class {
func someFunc()
}
// UICollectionViewCell
final class MessageCollectionViewCell: UICollectionViewCell {
weak var delegate: MyCollectionViewCellDelegate?
}
После этих простых изменений всё стало прекрасно - после возвращения назад из UIViewController использование памяти возвращается на исходный уровень.
comment comments