#ios #swift #closures #coordination
#iOS #swift #замыкания #координация
Вопрос:
Я столкнулся с этим странным использованием замыкания в ссылке
Приведенный ниже код представляет собой упрощенную версию в Xcode Playground
typealias AppStateDeeplinkAction = () -> ()
var deeplinkBlock : AppStateDeeplinkAction? = {
print ("this is for deeplink")
}
func deeplinkAction() {
if let deeplinkAction = deeplinkBlock {
print("deeplink is executed")
deeplinkAction() // <- if this is commented out, the result is just "deeplink is executed"
}
}
deeplinkAction()
Результатом этого является,
deeplink is executed
this is for deeplink
Что сбивает с толку, функция deeplinkAction() вызывается внутри if-let, и ошибки времени компиляции / выполнения нет. Все закончилось успешно. Чего я не совсем понимаю, так это рекурсивный вызов Deeplink Action() .
По сравнению с этим, если Deeplink Action() закомментирован, результат просто
deeplink is executed
Какую функцию «замыкания» мне не хватает? Как я должен это интерпретировать?
Комментарии:
1. Я бы назвал их по-другому
if let
:if let other = deeplinklBlock { print... other() }
. Это то же самое, когда вы выполняетеif let
и называете его так же, как var . Это может сбивать с толку, и здесь может быть слишком плохо, если метод будет назван как var.2. Да, теперь мне все ясно. Большое спасибо ~
Ответ №1:
Здесь нет рекурсивного вызова, но использование того же имени для необязательной связанной переменной замыкания, что и для заключающей функции, вводит в заблуждение и, следовательно, является плохой идеей.
Просто переименуйте его, и все станет ясно. Круглые скобки после переменной закрытия выполняют указанное закрытие, поэтому deeplinkBlock()
выполните закрытие, хранящееся в deeplinkBlock
переменной.
typealias AppStateDeeplinkAction = () -> ()
var deeplinkBlock : AppStateDeeplinkAction? = {
print ("this is for deeplink")
}
func deeplinkAction() {
if let deeplinkBlock = deeplinkBlock {
print("deeplink is executed")
deeplinkBlock()
}
}
deeplinkAction()
На самом деле, в любом случае нет необходимости в необязательной привязке, вы также можете использовать необязательную цепочку для замыканий.
func deeplinkAction() {
deeplinkBlock?()
}