Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios associatedType为class的协议的扩展?_Ios_Swift_Generics_Protocols_Associated Types - Fatal编程技术网

Ios associatedType为class的协议的扩展?

Ios associatedType为class的协议的扩展?,ios,swift,generics,protocols,associated-types,Ios,Swift,Generics,Protocols,Associated Types,我试过这样的方法: protocol MyModelProtocol { var name: String { get set } } protocol MyProtocol { associatedtype Model: MyModelProtocol func changeModel(_ model: Model) } extension MyProtocol where Model: AnyObject { } 编译器很高兴。然而,在这个扩展中,编译器仍然不

我试过这样的方法:

protocol MyModelProtocol {
    var name: String { get set }
}

protocol MyProtocol {
    associatedtype Model: MyModelProtocol

    func changeModel(_ model: Model)
}

extension MyProtocol where Model: AnyObject {
}
编译器很高兴。然而,在这个扩展中,编译器仍然不确定模型是类还是结构。例如:

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参数”。

您可以只向变量添加中间赋值。对于类/引用类型,这与在原始引用上设置属性具有相同的效果。对于一个结构类型,它将创建一个副本,这将不起作用,但应该通过扩展上的约束来避免

func changeModel(_ model: Model, completion: @escaping () -> Void) {
    var modelRef = model
    Api.shared.doRandomAsyncStuff() { (_) in             
        modelRef.name = "changed"
        completion()
    }
}

您是否也需要值类型(struct、enum)采用该协议?否则您可以定义一个类协议:
protocol MyModelProtocol:class{..}
Yes,我可以。我以前也有过,但因为我现在也想使用structs,所以我不得不删除这些代码。太棒了!非常简单!我只是测试了一下,它成功了。谢谢你的帮助。