Сегодня Widget использует больше памяти каждый раз, когда обновляется, а затем в конечном итоге падает
Я работаю над виджетом сегодня и сталкиваюсь с проблемами с памятью.
Когда я запускаю виджет и наблюдаю за использованием памяти XCode, виджет использует около 15 МБ при первом запуске. Затем, когда я провожу пальцем от экрана виджета и обратно, он достигает примерно 16 МБ.
Каждый раз, когда я убираю и возвращаю обратно, использование памяти увеличивается примерно на 0,5–1,5 МБ. Поскольку я делаю это больше, я получаю предупреждения памяти (didReceiveMemoryWarning()
называется) и в конце концов, при более сильном смахивании виджет падает.
Все эти симптомы проявляются во время тестирования на iPhone X. На симуляторе виджет запускается с использованием около 50 мегабайт, что кажется странным, но он ведет себя так же, когда использование памяти увеличивается с каждым разом, когда я провожу пальцем назад,
Я попытался проанализировать это с помощью инструментов, но я могу только заставить инструменты показывать, что происходит в начале (когда я впервые запускаю виджет), и он не продолжает работать, когда я провожу назад и назад.
В процессе устранения (комментируя реальную функциональность моего виджета) проблема все еще возникает, когда остается только код пользовательского интерфейса. Это заставляет меня думать, что это проблема с моим подходом пользовательского интерфейса.
В прошлом я создавал виджеты Today, но всегда использовал Interface Builder. На этот раз я решил построить интерфейс программно. Я не вижу такого же поведения увеличения использования памяти при каждом обновлении, когда смотрю на другие виджеты Today, которые я создал с помощью Interface Builder.
Во-первых, я настроил все свои элементы пользовательского интерфейса как приватные переменные типа lazy, например:
private lazy var mainStackView: UIStackView = {
let stackView = UIStackView()
stackView.distribution = .fillEqually
stackView.translatesAutoresizingMaskIntoConstraints = false
return stackView
}()
Затем в viewDidLoad()
Я добавляю свои взгляды к TodayViewController
с некоторыми ограничениями, например:
view.addSubview(mainStackView)
let stackViewLeadingConstraint = mainStackView.leadingAnchor.constraintEqualToSystemSpacingAfter(view.leadingAnchor, multiplier: 1)
let stackViewTopConstraint = mainStackView.topAnchor.constraintEqualToSystemSpacingBelow(view.topAnchor, multiplier: 1)
let stackViewTrailingConstraint = view.trailingAnchor.constraintEqualToSystemSpacingAfter(mainStackView.trailingAnchor, multiplier: 1)
let stackViewBottomConstraint = view.bottomAnchor.constraintEqualToSystemSpacingBelow(mainStackView.bottomAnchor, multiplier: 1)
view.addConstraints([stackViewLeadingConstraint, stackViewTopConstraint, stackViewTrailingConstraint, stackViewBottomConstraint])
Так как я новичок в построении пользовательского интерфейса программным способом, есть ли что-либо с таким подходом, которое кажется явно некорректным и может вызвать утечку памяти?
Я даже пытался закомментировать весь мой код и запустить его с простой пробел UIViewController
где функции жизненного цикла представления даже ничего не делают, и я все еще испытываю утечку памяти. Это заставляет меня думать, что я должен делать что-то, когда я программно создаю интерфейс, а я этого не делаю.
Кажется, что-то не выпускается и дублируется в памяти каждый раз, когда появляется виджет сегодня. Я был бы признателен за любые предложения о том, как найти то, что не было выпущено, и заставить систему выпустить это. Спасибо!
РЕШИТЬ
Благодаря совету по устранению неполадок, предоставленному Кристофером Пиксли, я смог отследить проблему. Это оказалась моя вина. Чтобы устранить предыдущую несвязанную проблему, я включил в схему объекты-зомби, и она все еще была включена. Как только я выключил это, проблема ушла. Это настройка, о которой я говорю:
1 ответ
Я не вижу проблем с тем, как вы создаете пользовательский интерфейс (из того, что вы уже делили). Вместо инструментов попробуйте использовать отладчик графика памяти, чтобы найти утечку.
Это приостановит отладчик, и вы можете использовать верхнюю панель для просмотра всех распределений и того, что указывает на каждый экземпляр. Откройте отладчик графа памяти, посмотрите на свой график, затем отмените паузу и несколько раз прокрутите расширение и снова на экране и снова откройте отладчик графа памяти. Это должно дать вам лучшее представление о том, что протекает и что на нем держится.