Reputation: 411
I am having issue with storing the value from a escaping closure.
Basically I have a get request function with a escaping completionHandler. The signature looks like this:
struct NetworkRequest {
func getRequest(completionHandler: @escaping (_ result: [String)]?) -> Void) {
// implementations
}
}
Now I have a struct that calls this method. Something like this:
struct foo {
var value: [String]?
lazy var networkRequest = NetworkRequest()
func testGet() {
networkRequest.getRequest((result) {
self.value = result // here's my issue
}
}
}
I am getting this "Closure cannot implicitly capture a mutating self parameter" error
I need to store the result value but I couldn't. How do I resolve this issue?
Upvotes: 1
Views: 277
Reputation: 13302
The behavior you are trying to achieve by using structs isn't possible in Swift 3.
I would suggest to make foo
a class instead of struct.
This will work if using struct isn't critical for you.
Here is updated code:
struct NetworkRequest {
func getRequest(completionHandler: @escaping ([String]?) -> Void) {
// implementations
}
}
class foo {
var value: [String]?
lazy var networkRequest = NetworkRequest()
func testGet() {
networkRequest.getRequest { result in
self.value = result
}
}
}
The reason why your code can not be complied is the copy by value
nature of structs:
In your example getRequest
has @escaping
closure completionHandler
and struct foo
tries to modify itself inside this closure implementation. But to be sure that self
exists at the moment when completionHandler
is called compiler needs to copy self
. In structs copy
means creating new instance. That means in self.value = result
self
is new instance of foo
struct. And modifying this new instance doesn't make any sense because you as consumer of this struct will never get this new instance.
It works with classes because they copy by reference. That means in self.value = result
self
is the same instance as before.
Upvotes: 3