2016-04-23 154 views
2

我有一些實現Resource協議的結構。這定義它們必須具有符合ExtendedInfo協議的變量extendedInfo,以便通過init(json: [String: AnyObject]提供使用json初始化它們的方式。我試圖提供一種方法來動態實例化這些,使用JSON,提供正確類型的ExtendedInfo並將其分配給結構的extendedInfo變量。然而,試圖通過他們的dynamicTypeSwift動態類型初始化與動態協議類型

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 

任何想法傢伙來實例化他們時,我得到一個Argument labels '(json:)' do not match any available overloads錯誤?由於

回答

1

首先,你不需要明確定義的ExtendedInfoTypeAlias類型在你的結構實現中 - 你可以通過你爲提供的類型來推斷它。

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)

+0

太棒了。謝啦! – trundrumbalind

+0

@trundrumbalind高興地幫助:) – Hamish

-1

變化:

let user = User() 

要:

var user = User() 

,並嘗試這個辦法:

user.extendedInfo = UserExtendedInfo(json: sampleJSON) 
+0

的想法是,我沒有明確說哪個'... ExtendedInfo'對象我想初始化。我希望能夠從「extendedInfo」變量的類型中推斷出哪一個類型,以便它可以與遵守「Resource」協議的任何對象一起工作。 – trundrumbalind