Skip to content

Latest commit

 

History

History
40 lines (31 loc) · 1.92 KB

12.3 - Capturing Values.md

File metadata and controls

40 lines (31 loc) · 1.92 KB

A closure can capture constants and variables from the surrounding context in which it is defined. It can then refer to those constants and variables in its body, even if the original scope no longer exists.

In Swift, the simplest version of a closure that captures values is a nested function. For example, the following incrementor() function captures two parameters, amount and runningTotal:

func makeIncrementer(forIncrement amount: Int) -> () -> Int {
    var runningTotal = 0
    func incrementer() -> Int {
        runningTotal += amount
        return runningTotal
    }
    return incrementer
}

The total makeIncrementor(forIncrement: Int) function returns a function of type () -> Int. It takes no parameters, but is able to increment the runningTotal parameter repeatedly, as shown:

let incrementByTen = makeIncrementer(forIncrement: 10)

incrementByTen()
// returns a value of 10
incrementByTen()
// returns a value of 20
incrementByTen()
// returns a value of 30

It does this by capturing a reference to the amount and runningTotal parameters when it is first called. This gives it access to the parameters long after the initial makeIncrementor function has finished executing.

NOTE

As an optimization, Swift may instead capture and store a copy of a value if that value is not mutated by a closure, and if the value is not mutated after the closure is created.

Swift also handles all memory management involved in disposing of variables when they are no longer needed.

Previous Note | Back To Contents | Next Note