Я работаю с классами сетевых запросов, и я обеспокоен сбоями. Например, работа с закрытием очень проста, поскольку вы передаете метод обратного вызова функции:
// some network client
func executeHttpRequest(#callback: (success: Bool) -> Void) {
// http request
callback(true)
}
// View Controller
func reload() {
networkClient.executeHttpRequest() { (success) -> Void in
self.myLabel.text = "it succeeded" // NOTE THIS CALL
}
}
Однако, поскольку процесс, который должен выполнить обратный вызов, является асинхронным, когда обратные вызовы взаимодействуют с элементом класса контейнера (в данном случае классом UIKit
), он может быть уязвим для сбоев в таких ситуациях, как
- Пользователь перешел к другому диспетчеру просмотра, в то время как асинхронная задача все еще выполняла
- Пользователь нажал кнопку "домой", пока задача async все еще выполняла
- Etc...
Итак, когда обратный вызов, наконец, запускается, self.myLabel.text
может привести к сбою, поскольку диспетчер представлений, с которым self
ссылался, уже мог быть освобожден.
До этого момента. Правильно ли я или быстро внедряю что-то внутренне, чтобы этого не происходило?
Если я прав, то здесь, когда шаблон делегата пригодится, поскольку переменные делегата weak references
, а это значит, что они не хранятся в памяти, если они освобождены.
// some network client
// NOTE this variable is an OPTIONAL and it also a WEAK REFERENCE
weak var delegate: NetworkClientDelegate?
func executeHttpRequest() {
// http request
if let delegate = self.delegate {
delegate.callback(success: true)
}
}
Обратите внимание, что self.delegate
, так как это weak reference
, он будет указывать на nil
, если диспетчер представлений (который реализует протокол NetworkClientDelegate
) будет освобожден, и в этом случае вызов не будет вызван.
Мой вопрос будет: у закрытий есть что-то особенное, что делает их хорошим выбором в сценариях, подобных этому, вместо того, чтобы возвращаться к шаблону делегирования? Было бы неплохо, если бы были приведены примеры замыканий (которые не будут попадать в аварийные ситуации из-за указателя nil). Спасибо.