Не понимаю использование замыкания в шаблоне управления координатами / состоянием

#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?()
}