Today, we are going to learn about capturing value in the closure.
Firstly, we need to know What is closure?
According to Swift docs: Closures are self-contained blocks of functionality that can be passed around and used in your code. Closures can store references and capture to any constants and variables from the context in which they are defined.
Capturing Values in Closure
Closure can store references and capture values to any variables and constant from the context in which they are define, For example, class.
Swift can handle all of the memory management of capturing variables and constants.
For example:
1 2 3 4 5 6 7 8 |
var i = 0 var closureArr = [()->()]() for _ in 1...5 { closureArr.append { print(i) } i += 1 } |
1 2 3 4 5 6 |
Output:- closureArr[0]() // prints 5 closureArr[1]() // prints 5 closureArr[2]() // prints 5 closureArr[3]() // prints 5 closureArr[4]() // prints 5 |
We have created an empty closure for every iteration of the loop and added it to an array “closureArr”.
closure body contains only a single expression that prints the value of “i” .
Above closure captures the “i” current address and it returns the current value, every time we access “i”
Points related to capturing value:
- A closure can capture constants and variables from the surrounding context in which section it is declare.
- The closure can modify the values of those variables and constants from within its body, even if the original scope that variables and constants no longer exists.
- Swift also handles all memory management of variables when they are no longer in need.
- If we assign a closure to a property of a class instance, and the closure captures that instance by referring to the instance or its members, we will create a strong reference cycle between the instance and the closure
Capture list:
Swift uses capture lists to break strong reference cycles.
If we want to prevent capturing values behavior and print the value “i
“ even if the properties change after they’re captured inside the closure.
We can explicitly capture the variable with a capture list like this:
1 2 3 4 5 6 7 8 |
var closureArr2 = [()->()]() var j = 0 for _ in 1…5 { closureArr2.append { [j] in print(j) } j += 1 } |
1 2 3 4 5 6 |
Output:- closureArr2[0]() // prints 0 closureArr2[1]() // prints 1 closureArr2[2]() // prints 2 closureArr2[3]() // prints 3 closureArr2[4]() // prints 4 |
In this way, we keep an immutable copy of “j"
. Thanks to this copy, further changes “j"
, outside the closure, will not affect the closure. “j"
is a let constant here. It is not mutable.
In conclusion, we have learned about capturing values in closures.
Lastly, please share your thoughts and queries below.
For more blogs please click here