首页 > 解决方案 > 两个闭包有什么区别

问题描述

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()

标签: swiftescapingclosures

解决方案


这是正在发生的事情:

  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它调用闭包本身并将该闭包保存在某个属性中,以便您以后可以再次调用它。你通常做其中之一,但不是两者都做。


推荐阅读