Do I understand correctly that these parameters differ as follows: a declared closure with the escaping parameter will exist after exiting the function in which it is declared (for example, when passing a closure as a function parameter)?
1 answer
According to the documentation , you must mark the closure passed to the function as a parameter with the @escaping keyword if it is called after returning from the function.
It is a funeral effect.
In other words, if a closure is called asynchronously inside (callback) or outside (delegate) of a function, then you should mark it as @escaping.
Essentially, @escaping allows you to postpone the execution of the passed as a parameter of the closure to the moment you need (for example, by triggering a timer or by completing an asynchronous operation).
If you try to assign a non-escaping closure to a property of a class, structure, or enumeration, you will receive a compile-time error:
class MainDispatcher { var work: (() -> Void)? = nil func async(_ block: () -> Void) { self.work = block } } error: assigning non-escaping parameter 'block' to an @escaping closure self.work = block
If you try to cause a non-escaping closure asynchronously (that is, where an escaping closure is expected), you will also get a compile-time error:
class MainDispatcher { func async(_ block: () -> Void) { DispatchQueue.main.async { block() } } } Use of non-escaping parameter
By default, the closure passed as a parameter is non-escaping, so where you need it you must use the @escaping keyword.
class MainDispatcher { var work: (() -> Void)? = nil func async(_ block: @escaping () -> Void) { self.work = block DispatchQueue.main.async { self.work?() } } func sync(_ block: () -> Void) { DispatchQueue.main.sync { block() } } }