Search code examples
swiftparametersclosuresswift2

Can you have a closure that has both capture list and parameter list?


In Swift, how you create a closure that has both capture list and parameters?

I have used code presented in either form, but do not know how to create a closure that has both parameters and capture list.

e.g.

Closure with parameter list:

myFunction {
    (x: Int, y: Int) -> Int in
    return x + y
}

Closure with capture list:

myFunction { [weak parent = self.parent] in print(parent!.title) }

Example attempt with capture list:

class MyTest {
    var value:Int = 3

    func myFunction(f: (x:Int, y:Int) -> Int) {
        print(f(x: self.value, y: 5))
    }

    func testFunction() {
        myFunction {
            [weak self] (x, y) in   //<--- This won't work, how to specify weak self here?
            print(self.value)
            return self.value + y
        }
    }
}

Solution

  • The example you've given does work. To specify both a parameter list and a capture list you just do:

    exampleFunctionThatTakesClosure() { [weak self] thing1, thing2 in
    }
    

    However, creating a weak reference via a capture list means that self within your closure becomes an optional - as such, you have to unwrap (or force unwrap) it before you can use its value.

    For example, force unwrapping:

    func testFunction() {
        myFunction {
            [weak self] (x, y) in
            
            print(self!.value)
            return self!.value + y
        }
    }
    

    Or:

    func testFunction() {
        myFunction {
            [weak self] (x, y) in
            
            if let weakSelf = self {
                print(weakSelf.value)
                return weakSelf.value + y
            } else {
                return y
            }
        }
    }