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

时间:2016-04-23 20:20:53

标签: swift struct protocols dynamictype associated-types

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

实例化它们时出现dynamicType错误
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

任何想法的家伙?感谢

2 个答案:

答案 0 :(得分:1)

首先,您不需要在结构实现中明确定义ExtendedInfoTypeAlias的类型 - 您可以通过为extendedInfo提供的类型来推断它。< / p>

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 。 (This is a bug)。

<德尔> user.extendedInfo = user.extendedInfo!.dynamicType.init(json: sampleJSON)

答案 1 :(得分:-1)

更改:

let user = User()

要:

var user = User()

试试这个:

user.extendedInfo = UserExtendedInfo(json: sampleJSON)