2

Given the following definition:

func retrieveData(for id: Int, completion: @escaping (Record) -> ())

What is the difference between the following two calls to retrieveData?

first call:

let id: Int = 1 
retrieveData(id: id) {
    self.update(with: $0)
}

second call:

let id: Int = 1 
retrieveData(id: id, completion: {
    self.update(with: $0)
})
Asif Newaz
  • 557
  • 7
  • 17

2 Answers2

4

In the method,

func retrieveData(for id: Int, completion: @escaping (Record) -> ())

completion is a Trailing Closure. It is method's final argument. So, in Swift we can omit writing the argument label in the list while calling the method, i.e.

retrieveData(for: id) {
    //your code..
}

You can also call it like,

retrieveData(for: id, completion: {
    //your code..
}) 

So, it can be called in both ways. Your choice. Although the first one is more cleaner and recommended. Read more about it here.

PGDev
  • 23,751
  • 6
  • 34
  • 88
0

In addition to the accepted answer -

In Swift, functions are first class objects, that means that they can be passed as parameters.

In your examples, when there is a function that takes another function as an argument, you can either write the argument inline, using trailing closure syntax:

let id: Int = 1 
retrieveData(id: id) {
    self.update(with: $0)
}

But look at the function update(with:) it is a function that takes a Record and returns Void.

Another way to write this, rather than calling the function in the closure, is to just pass the function:

let id: Int = 1 
retrieveData(id: id, completion: update)

Notice that you don't pass it a parameter, or oven brackets. When you pass a function this way, you are passing the function itself, not the result of evaluating the function.

I think this is even cleaner at the call site.

Abizern
  • 146,289
  • 39
  • 203
  • 257