ios - 关联类型为类的协议(protocol)的扩展?

标签 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 {
}

编译器很高兴。然而,在这个扩展中,编译器仍然不确定模型是类还是结构。示例:

extension MyProtocol where Model: AnyObject {
    func changeModel(_ model: Model) {
        model.name = "changed"
    }
}

因此,我收到错误:“无法分配给属性:‘model’是‘let’常量”

我如何告诉编译器在该协议(protocol)扩展中关联的类型将始终是一个类?

顺便说一句,这只是一个简短的例子。我知道我可以在这种情况下使用 inout 参数,但它对我不起作用,因为我想像这样更改异步回调内部的对象:

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

尝试这样做会导致错误:“转义闭包只能按值显式捕获 inout 参数”。

最佳答案

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

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

关于ios - 关联类型为类的协议(protocol)的扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48207911/

相关文章:

Swift - 具有可交换性的模式匹配

java - 嵌套递归类型

java - 如何在Java 8中传递多个参数和一个函数,然后执行带参数的函数?

ios - 使用 card.io 扫描借记卡

ios - 辅助功能 VoiceOver 不适用于 UILabel

ios - 文件管理器有时在文档目录中找不到子文件夹

ios - 如果 view.bound.origin 总是 = (0, 0),它的目的是什么?

c# - 表示数字的值类型是否共享任何接口(interface)?

ios - swift 中的 .successor() 是什么?

ios - MvxBaseTouchViewPresenter : (ChoosePictureFromLibrary dialog does not appear)