Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass a closure as an optional parameter of the function

Tags:

ios

swift

swift3

I have a function which takes two parameters, the last parameter is a callback closure:

func myAsycTask(name: String, callback: @escaping ()->Void) {
   myQueue.async{
      self.doTask(name)
      callback()
   }
} 

func doTask(name: String) {...}

I would like to make the 2nd callback closure parameter optional. I tried to re-define the function above to:

func myAsycTask(name: String, callback: @escaping ()->Void? = nil) {
       myQueue.async{
          self.doTask(name)
          callback()
       }
} 

I get a compiler error:

Nil default argument value of cannot be converted to type '() ->'

How can I achieve what I need then?

like image 222
Leem Avatar asked Nov 07 '17 08:11

Leem


People also ask

How do you pass an optional parameter to a function?

To declare optional function parameters in JavaScript, there are two approaches: Using the Logical OR operator ('||'): In this approach, the optional parameter is Logically ORed with the default value within the body of the function. Note: The optional parameters should always come at the end on the parameter list.

Can a closure be passed parameters?

Because closures can be used just like strings and integers, you can pass them into functions. The syntax for this can hurt your brain at first, so we're going to take it slow. If we wanted to pass that closure into a function so it can be run inside that function, we would specify the parameter type as () -> Void .


2 Answers

Your current code means that Void is an optional return in the closure (which does not make much sense, since Void is already nothing). You should enclose the parameter in brackets and then make it optional.

func myAsycTask(name: String, callback: (() -> Void)? = nil)
like image 54
Tamás Sengel Avatar answered Oct 06 '22 17:10

Tamás Sengel


Try making your callback closure Optional and remove @escaping. @escaping annotation is pointless because your parameter is basically an enum (Optional is an enum with 2 cases: some(Value) and none) If your closure is owned by another type it is implicitly escaping.

import UIKit

// Also you can use a typealias to keep code more readable
typealias Callback = (() -> Void)

class Test {

    let myQueue = DispatchQueue(label: "com.playground")

    func doTask(name: String) {
        // something...
    }

    func myAsycTask(name: String, callback: Callback? = nil) {
        myQueue.async { [weak self] in
            self?.doTask(name: name)
            callback?()
        }
    }
}
like image 26
Oleh Zayats Avatar answered Oct 06 '22 15:10

Oleh Zayats