在函数返回后调用转义闭包是什么意思? [英] What does it mean to call an escaping closure after the function returns?

查看:210
本文介绍了在函数返回后调用转义闭包是什么意思?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读苹果开发者文档中关于转义闭包的定义。它说当一个闭包作为参数传递给函数时,一个闭包被称为转义函数,但在函数返回后被调用

I was reading the apple developer documentation's definition of escaping closures. It says "a closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns"

我不确定最后一部分应该是什么意思,在函数返回后是什么意思?这是否意味着在函数返回值之后?

I am not sure what the last part is supposed to mean, what does it mean by "after the function returns"? Does it mean "after the function returns a value"?

推荐答案

例如调用API。这个电话需要花费时间,但我们打算在通话完成后做一些事情。例如,假设我们想要使用我们提取的新数据刷新UITableView。如果我们立即执行此操作,则尚未收到数据:

Take for example a call to an API. This call is going to take time, but we are going to want to do something after the call is completed. For example, say we want to refresh a UITableView with the new data that we pull. If we were to do it immediately, the data wouldn't have been received yet:

ApiObject.getObjects(completion: { (error, objects) in })
tableView.reloadData()

如果我们要重新加载这里的数据,表视图将立即刷新(在我们实际收到数据之前)。通过在完成块中执行它,我们说,在完成函数时运行代码,而不是在函数实际返回时运行:

If we were to reload the data here, the table view will refresh immediately (before we actually have received the data). By doing it in the completion block, we are saying, run the code when we have completed the function, not when the function actually returns:

ApiObject.getObjects(completion: {(error, objects) in 
    self.tableView.reloadData()
})

这里我们在获取对象后运行它,而不是在函数本身到达结束时运行它。

Here we are running it once the objects have been fetched, not once the function itself has reached the end.

也许这会让事情变得更容易;我有以下代码:

Maybe this will make it easier; I have the following code:

let comeInAnimation = POPBasicAnimation(propertyNamed: kPOPLayoutConstraintConstant)!
comeInAnimation.toValue = 0
comeInAnimation.completionBlock = { (anim, success) -> Void in
    self.loginButton.enabled = true
    self.signupButton.enabled = true
}
signUpContainingViewLeftConstraint.pop_add(comeInAnimation, forKey: AnimationString.EnterExit.identifier)

这是使用POP动画框架。在这种情况下,我有一个登录和注册按钮,但我也有一个动画供他们出现。我不希望按钮在它们出现时被点击,所以我将它们的启用设置为false。现在您可以看到它们已设置为在completionBlock中启用。这意味着,当动画完成时,完成块被调用,我知道现在是时候设置它们被启用了。我是这样做的:

This is using the POP animation framework. In this case, I have a login and signup button, but I also have an animation for them to appear. I dont want the buttons to be clicked while they are appearing so i have their enabled set to false originally. Now you can see they get set to enabled in the completionBlock. This means, when the animation is completed, the completion block gets called and I know now is the time to set them to be enabled. Had I done it like so:

let comeInAnimation = POPBasicAnimation(propertyNamed: kPOPLayoutConstraintConstant)!
comeInAnimation.toValue = 0
signUpContainingViewLeftConstraint.pop_add(comeInAnimation, forKey: AnimationString.EnterExit.identifier)
self.loginButton.enabled = true
self.signupButton.enabled = true

即使在调用动画后设置了启用的属性,实际上也会在动画之前设置属性做完了。因为程序逐行运行,所以添加动画然后立即设置属性(这太早了)。

Even though the enabled properties are set after the animation is called, the properties are actually being set before the animation is complete. Because the program runs line by line, the animation gets added and then immediately the properties are set (this is too early).

注意:这是一个问题,因为这些函数是异步运行的。也就是说,它允许程序在执行其操作时继续运行。如果这行代码被阻止(在程序竞争之前停止程序),那么将代码放在一个完成块中并立即放入它将是同样的事情。但在现实生活中,我们不想阻止,因为它给出了程序冻结的外观。

Note: This is an issue because these functions run asynchronously. That is, it allows the program to keep running while it is doing its thing. If this line of code blocked (stopped the program until it was compete) then putting the code in a completion block and putting it immediately after would be the same thing. In real life though, we dont want to block because it gives the appearance that the program has frozen.

这篇关于在函数返回后调用转义闭包是什么意思?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆