我试过这样的事情:
protocol MyModelProtocol {
var name: String { get set }
}
protocol MyProtocol {
associatedtype Model: MyModelProtocol
func changeModel(_ model: Model)
}
extension MyProtocol where Model: AnyObject {
}
编译器很高兴。但是,在此扩展中,编译器仍然不确定Model是类还是结构。例如:
extension MyProtocol where Model: AnyObject {
func changeModel(_ model: Model) {
model.name = "changed"
}
}
因此,我得到错误:“无法分配给属性:'model'是'let'常量”
如何告诉编译器在该协议扩展中,关联类型将始终是一个类?
不过,这只是一个简短的例子。我知道在这种情况下我可以使用inout参数,但它对我不起作用,因为我想改变异步回调内的对象,如下所示:func changeModel(_ model: inout Model, completion: @escaping () -> Void) {
Api.shared.doRandomAsyncStuff() { (_) in
model.name = "changed"
completion()
}
}
尝试这样做会让我误以为:“转义闭包只能通过值明确捕获inout参数”。
答案 0 :(得分:1)
您只需向var添加中间分配即可。对于类/引用类型,这与在原始引用上设置属性具有相同的效果。对于结构类型,它会创建一个副本,这不起作用,但应该通过扩展的约束来避免。
func changeModel(_ model: Model, completion: @escaping () -> Void) {
var modelRef = model
Api.shared.doRandomAsyncStuff() { (_) in
modelRef.name = "changed"
completion()
}
}