Сильный, слабый или неизвестный в эталонном цикле с таймером - PullRequest
1 голос
/ 25 апреля 2019

У меня есть UIViewController, который имеет ссылку на Timer объект, который неоднократно вызывает замыкание.Объект Timer захватывает self в своем блоке.Насколько я понимаю, это приводит к retains cycle между контроллером вида и блоком.Существует логика для установки таймера на ноль, и затем цикл сохранения прерывается, но он может не выполняться.

У меня следующий вопрос: View Controller будет существовать столько, сколько длится приложение (по крайней мере, в текущей реализации).В этом случае - как мне лучше всего позаботиться об этом цикле сохранения?Должен ли я игнорировать это, поскольку контроллер View не будет выпущен в любом случае.Должен ли я рассмотреть возможные будущие изменения и обработать их с помощью ссылок unowned или weak и какой.Я предполагаю, что это должно быть unowned, поскольку таймер удерживается только контроллером представления, и его следует разблокировать после освобождения контроллера представления, но не уверен, что я что-то упустил.Заранее спасибо.Следующий код является простым примером того, о чем я говорю.Class A - это контроллер вида.

class A {

    var timer: Timer? = nil
    var varToReference: Int = 0

    func startTimer() {
        timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {  (theTimer) in

            self.varToReference += 1

        })
    }

    func stopTimer() {
        if let theTimer = timer {
            theTimer.invalidate()
            timer = nil
        }
    }

    func onAdapterStarts() {
        self.startTimer()
    }

    func onAdapterStops(){
        self.stopTimer()
    }

    deinit {
        print("A Deinit")
    }

}

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

В вашем случае weak и unowned допустимы. С простым кодом внутри блока таймера я предлагаю использовать weak, в противном случае вы можете предпочесть unowned. Используйте weak, чтобы заботиться о будущих обновлениях и расширениях вашего проекта.

timer = Timer.scheduledTimer(withTimeInterval: 2, repeats: true, block: {[weak self] (theTimer) in

        self?.varToReference += 1

    })
1 голос
/ 25 апреля 2019

Цикл сохранения - это состояние, когда два объекта сохраняют ссылку друг на друга и сохраняются; создается цикл, поскольку оба объекта пытаются сохранить друг друга.

Теперь давайте возьмем ваш пример кода

В вашем примере Class A владеет замыканием через переменную timer.Если вы не объявите self как weak или unowned, закрытию также будет принадлежать self, создающее сильный ссылочный цикл.

Разница между unowned и weak

Простая разница между unowned и weak заключается в том, что weak объявляется необязательным, а unowned - нет.Объявляя это weak, вы получаете возможность обрабатывать случай, когда в какой-то момент он может быть nil внутри затвора.Если вы попытаетесь получить доступ к переменной unowned, которая оказывается nil , она приведет к краху всей программы.Поэтому используйте unowned только в том случае, если вы уверены, что переменная всегда будет рядом, пока закрытие около

Всегда будьте готовы к работе, поскольку ваша работа в любом мобильном приложении всегда должна быть расширяемой.

См. Этот принятый ответ для лучшего понимания.

...