Swift: самостоятельная ссылка во вложенных замыканиях - PullRequest
0 голосов
/ 22 октября 2018

Я использую новый блочный KVO API в Swift для наблюдения за свойствами.Ниже приведен пример кода.

class A: NSObject {
var observerA: NSKeyValueObservation? = nil
var observerB: NSKeyValueObservation? = nil

var property1: CustomObj1?
var property2: CustomObj2?

func doSomething() {

}

func doSomethingElse() {

}

func observeValues() {
    observerA = customObj1.observe(\.property1, options: [], changeHandler: { [weak self] (obj, change) in
        guard let strongSelf = self else { return }
        strongSelf.doSomething()
        strongSelf.observerB = customObj2.observe(\.property2, options: [], changeHandler: { [weak strongSelf] (nestedObj, nestedChange) in
            guard let nestedStrongSelf = strongSelf else { return }
            nestedStrongSelf.doSomethingElse()
        })
    })
}

}

Мой вопрос: как мы ссылаемся на self во внутреннем блоке обработчика изменений?Я мог бы использовать его, как указано выше, и я не вижу утечек памяти.Но использование self вместо strongSelf в "[strong strongSelf]" в обработчике внутренних изменений также не вызывает никаких проблем.Вот код

func observeValues() {
observerA = self.observe(\.property1, options: [], changeHandler: { [weak self] (obj, change) in
    guard let strongSelf = self else { return }
    strongSelf.doSomething()
    strongSelf.observerB = strongSelf.observe(\.property2, options: [], changeHandler: { [weak self] (nestedObj, nestedChange) in
        guard let nestedStrongSelf = self else { return }
        nestedStrongSelf.doSomethingElse()
    })
})

}

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

1 Ответ

0 голосов
/ 22 октября 2018

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

Например, если этот VC активен в течение всего времени жизни приложения, даже еслизакрытие захватывало сильный референтный цикл, оно ничего не сделало бы.Влияние будет таким же: VC будет работать в течение всего времени жизни приложения, что он уже делал в любом случае.

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

...