2017-08-31 99 views
1

我有一個init方法用JSON數據初始化我的模型,但是當我想在NSUserDefaults中存儲這個對象時,需要創建acoder和adecoder init方法。用編碼器vs Json處理Object init?

即時得到錯誤:

Cannot invoke 'UserProfileModel.init' with an argument list of type '(apiKey: String, userID: String, userEmail: String, lastName: String, firstName: String, company: String, userImage: String, jobTitle: String)'

爲aDecoder初始化爲:

required convenience init(coder aDecoder: NSCoder) { 
    let apiKey = aDecoder.decodeObject(forKey: "apiKey") as! String 
    let userID = aDecoder.decodeObject(forKey: "userID") as! String 
    let userEmail = aDecoder.decodeObject(forKey: "userEmail") as! String 
    let lastName = aDecoder.decodeObject(forKey: "lastName") as! String 
    let firstName = aDecoder.decodeObject(forKey: "firstName") as! String 
    let company = aDecoder.decodeObject(forKey: "company") as! String 
    let userImage = aDecoder.decodeObject(forKey: "userImage") as! String 
    let jobTitle = aDecoder.decodeObject(forKey: "jobTitle") as! String 
    self.init(apiKey: apiKey, userID: userID, userEmail: userEmail, lastName: lastName, firstName: firstName, company: company, userImage: userImage, jobTitle: jobTitle) 
} 

,但我已經有這個初始化:

init?(_ json: JSON) { 
    // Map API Key from top level 
    guard let apiKey = json["apikey"].string 
    else { return nil } 

    // assign user 
    guard let userID = json["user"]["id"].string, 
      let userEmail = json["user"]["email"].string, 
      let lastName = json["user"]["lastname"].string, 
      let firstName = json["user"]["firstname"].string 
    else { return nil } 

    // assign optionals to user 
    let company = json["user"]["company"].string 
    let userImage = json["user"]["image"].string 
    let jobTitle = json["user"]["jobtitle"].string 

    // Assign to model properties 
    self.apiKey = apiKey 
    self.userID = userID 
    self.userEmail = userEmail 
    self.lastName = lastName 
    self.firstName = firstName 
    self.company = company 
    self.userImage = userImage 
    self.jobTitle = jobTitle 
} 

如何兼顧雙方無勞動拋出這個錯誤?

回答

2

使您的解碼器功能成爲必需的init,而不是便利的init。

required init(coder aDecoder: NSCoder) { 
    self.apiKey = aDecoder.decodeObject(forKey: "apiKey") as! String 
    self.userID = aDecoder.decodeObject(forKey: "userID") as! String 
    self.userEmail = aDecoder.decodeObject(forKey: "userEmail") as! String 
    self.lastName = aDecoder.decodeObject(forKey: "lastName") as! String 
    self.firstName = aDecoder.decodeObject(forKey: "firstName") as! String 
    self.company = aDecoder.decodeObject(forKey: "company") as! String 
    self.userImage = aDecoder.decodeObject(forKey: "userImage") as! String 
    self.jobTitle = aDecoder.decodeObject(forKey: "jobTitle") as! String 
} 

這就是所有:)希望它可以幫助

問題是什麼?

在iOS中,所有便利的init應該最終調用指定的初始化程序。在你的情況下,你已經有了一個接受jSON的指定初始化器。現在兩種解決方案

一個聲明指定的init這需要像你在你的代碼的init(coder aDecoder: NSCoder)和最後一行中所使用的所有的值讓你init(_ json: JSON)也是一個方便的初始化並最終在這兩個init(coder aDecoder: NSCoder)init(_ json: JSON)調用指定的初始化

其他只需使用上面指定的第二種簡單方法即可。

編輯:

如果我做它需要的,我怎麼做用JSON來初始化?生病也需要這樣做?

是的,你需要寫required init(coder aDecoder: NSCoder) {因爲你確認NSCoding協議和NSCoding協議希望你實現這個初始化。因此它是一個必需的init。

作爲您的init(_ json: JSON) {是您的班級的指定初始值設定項。

指定初始值設定項和所需初始值設定項有什麼區別?

請閱讀:What's the difference between a required initializer and a designated initializer?

因爲它清楚地總結

  • 需要initialisers不必指定。
  • 指定的初始化器不一定需要。
+0

如果我使它成爲必需,我如何用JSON初始化?生病也需要這樣做? – jackdm

+0

@jackdm:請閱讀我更新的答案我已經指定了爲什麼你不需要self.init –

+0

@jackdm:請閱讀更新的答案。如果有任何混淆,請讓我知道 –