What does it mean to call an escaping closure afte

2019-03-02 07:46发布

This question already has an answer here:

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"?

1条回答
戒情不戒烟
2楼-- · 2019-03-02 08:05

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.


Edit

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)

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.

查看更多
登录 后发表回答