两种闭包有什么区别

时间:2019-06-11 03:09:25

标签: swift escaping closures

我尝试在以下代码中注释和取消注释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 :(得分:0)

这是怎么回事:

  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语句被两次调用。

这就是为什么第一个移演仅调用一次闭包,而第二个移出两次调用闭包的原因。


通常,当您将闭包传递给方法时,您可以(a)从方法内部调用闭包(也许在某些完成处理程序之类的程序中);或者或(b)将闭包保存在某些属性中,以便稍后使用。

因此,第二个示例非常不寻常,其中outsideActivity都调用闭包本身并将该闭包保存在某些属性中,以便您以后可以再次调用它。您通常会做一个或另一个,但不能两者都做。