Сегодня 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где функции жизненного цикла представления даже ничего не делают, и я все еще испытываю утечку памяти. Это заставляет меня думать, что я должен делать что-то, когда я программно создаю интерфейс, а я этого не делаю.

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


РЕШИТЬ

Благодаря совету по устранению неполадок, предоставленному Кристофером Пиксли, я смог отследить проблему. Это оказалась моя вина. Чтобы устранить предыдущую несвязанную проблему, я включил в схему объекты-зомби, и она все еще была включена. Как только я выключил это, проблема ушла. Это настройка, о которой я говорю: Флажок Зомби Объекты в Xcode

1 ответ

Решение

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

Отладчик графа памяти

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

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