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.