how value type is capture in a closure and the changes of the value type are observed?

Generated on 8/9/2024

1 search

In Swift, when a value type is captured in a closure, the behavior depends on whether the closure is escaping or non-escaping.

For non-escaping closures:

  • The context can be allocated on the stack, and the address of that will be passed to the closure. This means the closure can handle this by just capturing a pointer to the variable's allocation. The lifetime of the variable is not extended beyond the scope of the function call.

For escaping closures:

  • The context object must be heap allocated and managed with retains and releases. The lifetime of the variable can be extended for as long as the closure is alive. The context essentially behaves like an instance of an anonymous Swift class. This allows changes to the variable to be observed in the original scope and vice versa.

Here's a relevant segment from the session Explore Swift performance:

In the closure function, we know the type of the paired context and can just pull the data we need out of it. Now this is different for escaping closures. We no longer know that the closure will only be used within the duration of the call. Therefore, the context object must be heap allocated and managed with retains and releases. The context essentially behaves like an instance of an anonymous swift class. Now in swift, when you refer to a local var in a closure, you capture that variable by reference. This allows you to make changes to the variable that will be observed in the original scope, and vice versa. If the Var is only captured by non escaping closures, this doesn't change the lifetime of the variable. As a result, the closures can handle this by just capturing a pointer to the variables allocation. But if the Var is captured by an escaping closure, the lifetime of the var can be extended for as long as the closure is alive. As a result, the VaR also has to be heap allocated, and the closure context has to retain a reference to that object.

For more details, you can refer to the chapter on Closures in the session "Explore Swift performance".