Swift 使用动态协议类型进行动态类型初始化

Swift dynamictype initialisation with dynamic protocol type

我有许多实现 Resource 协议的结构。这定义了它们必须有一个符合 ExtendedInfo 协议的变量 extendedInfo,以提供一种通过 init(json: [String: AnyObject] 使用 json 初始化它们的方法。我试图提供一种动态实例化这些的方法,使用 JSON,提供正确类型的 ExtendedInfo 并将其分配给结构的 extendedInfo 变量。但是,在尝试通过 dynamicType

实例化它们时出现 Argument labels '(json:)' do not match any available overloads 错误
protocol Resource {

    associatedtype ExtendedInfoTypeAlias: ExtendedInfo

    var extendedInfo: ExtendedInfoTypeAlias? { get set }
}

protocol ExtendedInfo {
    init(json: [String: AnyObject])
}

struct User: Resource {

    typealias ExtendedInfoTypeAlias = UserExtendedInfo

    let name: String = "Name"
    var extendedInfo: UserExtendedInfo?
}

struct UserExtendedInfo: ExtendedInfo {

    let age: Int?

    init(json: [String: AnyObject]) {
        age = json["age"] as? Int
    }
}


let user = User()
let sampleJSON = ["age": 50]

let userExtendedInfo = user.extendedInfo.dynamicType.init(json: sampleJSON) // Argument labels '(json:)' do not match any available overloads
user.extendedInfo = userExtendedInfo

有什么想法吗?谢谢

变化:

let user = User()

收件人:

var user = User()

试试这个:

user.extendedInfo = UserExtendedInfo(json: sampleJSON)

首先,你不需要在你的结构实现中显式定义 ExtendedInfoTypeAlias 的类型——你可以让它根据你为 extendedInfo 提供的类型来推断。

struct User: Resource {
    let name: String = "Name"
    var extendedInfo: UserExtendedInfo?
}

其次,您可以只使用给定结构的协议的关联类型 dynamicType 来使用给定的初始化程序。例如:

user.extendedInfo = user.dynamicType.ExtendedInfoTypeAlias.init(json: sampleJSON)
print(user.extendedInfo) // Optional(Dynamic_Protocols.UserExtendedInfo(age: Optional(50)))

至于为什么您当前的代码不起作用,我怀疑这是因为您从可选的 dynamicType 中获取了这一事实——这阻止了您在其上调用初始化程序。


我发现即使 extendedInfonil,下面的方法也有效。 ().

user.extendedInfo = user.extendedInfo!.dynamicType.init(json: sampleJSON)