По сути, в «обработчике завершения» нет ничего особенного.Это просто функция.
Если у вас есть функция:
func f() {
print("Hello, world")
}
, и вы не вызываете ее, что происходит потом?Ну, ничего не происходит.
Теперь, каковы последствия этого?Как упоминал Рмадди, если функция имеет завершение, вызов этого завершения, безусловно, ожидается вызывающими.Это необычно в лучшем случае для функции, выполняющей завершение, и вызывающей стороне не важно, выполняется ли когда-либо завершение. *
Представьте, что функция вызывается контроллером представления, который запускает действиеиндикатор, прежде чем он вызывает, а затем в завершении он останавливает индикатор.Если завершение никогда не вызывается, то индикатор никогда не прекращает вращаться.
По сути, все. Если завершение не вызывается, его код не запускается .Эффекты этого полностью зависят от того, что происходит в коде внутри и вокруг завершения.
Хорошо, вы упомянули память ... В большинстве случаев обработчик завершения будет анонимнымфункция.В этом случае - это созданный объект.Но он подчиняется тем же правилам управления памятью, что и любой другой объект.Нет утечки только потому, что она не называется.Если completeMe
выглядит так:
func completeMe(_ completionHandler: (String) -> Void) {
completionHandler("Hello, world")
}
и вы называете это так:
completeMe({ self.detailLabel.text = $0 })
Тогда объект, созданный для анонимной функции, не доживет до того момента, когда completeMe
возвращается.Если вы сохраняете анонимную функцию:
func completeMe(_ completionHandler: @escaping (String) -> Void) {
self.handler = completionHandler
// Do other things
}
Затем происходит то же самое, что и с любым другим объектом: анонимная функция действует до тех пор, пока этому свойству не будет присвоено другое значение (учитывая также, что ничто иное не имеет ссылки на него) .
И если вы передаете именованную функцию в,
func takeAString(_ s: String) {
print(s)
}
completeMe(takeAString)
время жизни takeAString
уже время жизни программы;здесь нет никаких последствий для управления памятью.
Если вы передадите метод экземпляра, управление памятью будет таким же, как если бы вы передали сам экземпляр.
* Обычно при сбоевозможно, вы либо а) будете иметь второе завершение "сбоя", либо б) завершение будет сигнализировать об ошибке через свой аргумент.