I tried something like this:
protocol MyModelProtocol {
var name: String { get set }
}
protocol MyProtocol {
associatedtype Model: MyModelProtocol
func changeModel(_ model: Model)
}
extension MyProtocol where Model: AnyObject {
}
The compiler goes happy. However, inside this extension the compiler still isn't sure if Model is class or struct. Example:
extension MyProtocol where Model: AnyObject {
func changeModel(_ model: Model) {
model.name = "changed"
}
}
Thus, I get the error: "Cannot assign to property: 'model' is a 'let' constant"
How can I tell the compiler that in that protocol extension the associated type will always be a class?
Btw, this is just a short example. I know I could use an inout parameter in this case, but it doesn't work for me because I want to change the object inside of an async callback like so:
func changeModel(_ model: inout Model, completion: @escaping () -> Void) {
Api.shared.doRandomAsyncStuff() { (_) in
model.name = "changed"
completion()
}
}
And trying to do this leads me to the error: "Escaping closures can only capture inout parameters explicitly by value".
You could just an add intermediate assignment to a var. For a class/reference type, this would have the same effect as setting a property on the original reference. For a struct type it would make a copy, which wouldn't work, but should be avoided by the constraint on the extension.
func changeModel(_ model: Model, completion: @escaping () -> Void) {
var modelRef = model
Api.shared.doRandomAsyncStuff() { (_) in
modelRef.name = "changed"
completion()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.