Hi all, I'm facing a problem that I came up with the following code (simplified for illustration purposes):
typealias Handler = (String) -> Void
// class B scope
var handlerSaver: Handler?
// saves the closure parameter (handler) to be executed later
classA.foo: ((Handler) -> Void) = { handler in
// error: Assigning non-escaping parameter 'handler' to an @escaping closure
handlerSaver = handler
}
// got stuff ...
handlerSaver("stuff")
// class A scope
var foo: ((Handler) -> Void)?
var handler = { (string: String) -> Void in
print("handle this \(string)")
}
// execute foo's closure with another closure (handler) as argument
foo?(handler)
Can this error be fixed? In other words I would like that class A calls foo but its handler being called later by class B. Is there any other way to achieve this instead of implementing a func handler(_ string: String) in class A; so the class B would call for it like so classA.handler("stuff") ?
Thanks!
If I got you correctly then this should help:
// got stuff ...
handlerSaver?("stuff")
^ missing
// class A scope
var foo: ((@escaping Handler) -> Void)?
^~~~~~~~~ this is missing
Just reshuffled everything a little:
typealias Handler = (String) -> Void
class A {
var foo: ((@escaping Handler) -> Void)?
}
let classA = A()
// class B scope
var handlerSaver: Handler?
// saves the closure parameter (handler) to be executed later
classA.foo = { handler in
// error: Assigning non-escaping parameter 'handler' to an @escaping closure
handlerSaver = handler
}
var handler = { (string: String) -> Void in
print("handle this \(string)")
}
// execute foo's closure with another closure (handler) as argument
classA.foo?(handler)
// got stuff ...
handlerSaver?("stuff")
Prints "handle this stuff".
2 Likes
Many thanks for the detailed answer!
The ((@escaping Handler) -> Void)? did the trick. I thought that the @escaping keyword could only be used in func declarations.