Быстрое управление памятью: правильное создание видов и предотвращение утечек памяти - PullRequest
2 голосов
/ 25 сентября 2019

Я немного запутался в отношении управления памятью Swift.Я понимаю, что removeFromSuperview освобождает представление и делает его пригодным для сбора мусора, если retainCount равно 0. Однако после отслеживания CFGetRetainCount(myView) я не уверен, как вычисляется retainCount и как правильно убедиться, что представлениебудет полностью освобожден после вызова removeFromSuperview.

Это то, что я получаю для простой UILabel.Код:

let myLabel = UILabel()
   print("After creation")
   print(CFGetRetainCount(myLabel))
myLabel.frame = CGRect(x: 0, y: 0, width: view.frame.width - 40, height: 60)
   print("After frame set")
   print(CFGetRetainCount(myLabel))
myLabel.text = "Lorem ipsum"
myMainView.addSubview(myLabel)
   print("After added to superview")
   print(CFGetRetainCount(myLabel))

let otherLabel = UILabel()
otherLabel.frame = CGRect(x: 0, y: myLabel.frame.maxY + 20, width: view.frame.width - 100, height: 60)
   print("After referenced to position other view")
   print(CFGetRetainCount(myLabel))

myLabel.removeFromSuperview()
   print("After removed from superview")
   print(CFGetRetainCount(myLabel))

Консоль:

After creation
3
After frame set
3
After added to superview
4
After referenced to position other view
4
After removed from superview
3

Это приводит меня к нескольким вопросам:

1) Я понимаю, что CFGetRetainCount содержит слабые ссылки, но как это происходит после 3Я только что создал UILabel?

2) Я добавляю представления внутри функции без ссылки на класс, когда они мне не нужны позже (я тоже могу добавить gestRecognizer) и удаляю их перед удалением содержащихсмотреть с:

myMainView.subviews.forEach({
   $0.removeFromSuperview()
})

Это считается хорошей практикой?Препятствия жеста-распознавателя предотвращают освобождение памяти?

3) Как убедиться, что память освобождается, когда счетчик уже равен 3, когда я создаю представление?

Чего мне не хватает?

Ответы [ 2 ]

1 голос
/ 25 сентября 2019

ссылка, которой поделился ДонМаг выше, объясняет, почему вы не должны использовать retainCount.Ручки ARC сохраняют счет для вас.что вам нужно беспокоиться о том, чтобы сохранить циклы.Ничто из того, что вы упомянули, делая выше, не должно создавать цикл сохранения, поэтому вы должны верить, что компилятор удалит метку из памяти до тех пор, пока на нее больше нет ссылок.распространенные случаи использования, где происходят циклы сохранения, - это делегаты и блоки, которые ссылаются на себя и другие объекты.

0 голосов
/ 26 сентября 2019

Таким образом, для тех, кто останавливается здесь и интересуется тем же, CFGetRetainCount возвращает ненадежные результаты, как указано здесь .

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

deinit {
  print("Memory deallocated")
}

Если ваш объект не сохраняется, автоматически вызывается метод выше.См. Документацию здесь: https://docs.swift.org/swift-book/LanguageGuide/Deinitialization.html

Другие утечки могут быть проверены с использованием инструментов (в Xcode: Product> Profile> Leaks) или с помощью инструмента График отладочной памяти

enter image description here

Дополнительные объяснения здесь: https://www.youtube.com/watch?v=1LnipXiSrSM

Поэтому ответы будут следующими:

1 + 3) Не используйте CFGetRetainCount.См. Объяснение выше.

2) Кажется, это работает нормально, и когда я тестирую приложение, освобождается память.

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