Какая разница между двумя замыканиями - PullRequest
0 голосов
/ 11 июня 2019

Я попытался прокомментировать и раскомментировать activity() в следующем коде.Когда я прокомментировал activity(), я обнаружил, что результат на игровой площадке просто однажды покажет «играть в теннис».Однако, если я оставлю комментарий activity(), он будет показан дважды.В чем разница между двумя утверждениями?

class Baby {
    var name = "peter"
    var favoriteActivity: (() -> ())!

    func outsideActivity(activity: @escaping () -> ()) {
        //activity()
        favoriteActivity = activity
    }
}

var cuteBaby = Baby()
cuteBaby.outsideActivity {
    print("play tennis")
}
cuteBaby.favoriteActivity()

1 Ответ

0 голосов
/ 11 июня 2019

Вот что происходит:

  1. Рассмотрим этот метод:

    func outsideActivity(activity: @escaping () -> ()) {
        //activity()
        favoriteActivity = activity
    }
    

    Все, что нужно, это сохранить закрытие в свойстве favoriteActivity

    Таким образом, когда вы делаете:

    // create `Baby` instance
    
    var cuteBaby = Baby()
    
    // this method saves closure in `favoriteActivity`, but doesn’t call it
    
    cuteBaby.outsideActivity {
        print("play tennis")
    }
    
    // this now calls the closure
    
    cuteBaby.favoriteActivity()
    

    Все, что делает метод outsideActivity, это сохраняет замыкание в свойстве с именем favoriteActivity.

    Таким образом, вы видите одно print утверждение.

  2. Однако теперь рассмотрим этот метод:

    func outsideActivity(activity: @escaping () -> ()) {
        activity()
        favoriteActivity = activity
    }
    

    Это фактически вызывает замыкание перед сохранением его в свойстве.

    Итак, когда вы делаете:

    // create `Baby` instance
    
    var cuteBaby = Baby()
    
    // this method both calls the closure and then also saves it in `favoriteActivity`
    
    cuteBaby.outsideActivity {
        print("play tennis")
    }
    
    // this now calls the saved closure a second time
    
    cuteBaby.favoriteActivity()
    

    В этом случае вы увидите, что ваш оператор print вызывается дважды.

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


Обычно, когда вы передаете закрытие методу, вы либо (а) вызываете закрытие изнутри метода (возможно, в каком-то обработчике завершения или тому подобном); или (б) сохранить закрытие в каком-либо свойстве, чтобы вы могли вызвать его позже.

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

...