【问题标题】:Creating a second failable initializer using a convenience initializer使用便利构造器创建第二个可失败构造器
【发布时间】:2017-02-12 01:54:07
【问题描述】:

我正在尝试创建第二个可失败的便利初始化程序以使用,因为我想进行两次 API 调用,并且第二个可失败初始化程序包含我将从原始 API 获得的所有属性,这与第一个包含所有属性的可失败初始化程序不同原始属性以及我添加的一些其他属性,我将在这些属性上发布到 firebase。

class Alcohol {
    var id: Int
    var companyName: String
    var address: String
    var city: String
    var state: String
    var postal: String
    var country: String
    var phone: String
    var email: String
    var url: String
    var checkedBy: String
    var notes: String
    var status: String
    var statusColor: String
    var identifier: NSUUID?
    var barnivoreChecked: Bool?
    var alcoholType: AlcoholType?

    // This failable init is for the information I'll be retrieving from firebase.

    init?(dictionary: [String: AnyObject], type: AlcoholType) {
        guard
            let id = dictionary[Constants.kID] as? Int,
            let companyName = dictionary[Constants.kCompanyName] as? String,
            let address = dictionary[Constants.kAddress] as? String,
            let city = dictionary[Constants.kCity] as? String,
            let state = dictionary[Constants.kState] as? String,
            let postal = dictionary[Constants.kPostal] as? String,
            let country = dictionary[Constants.kCountry] as? String,
            let phone = dictionary[Constants.kPhone] as? String,
            let email = dictionary[Constants.kEmail] as? String,
            let url = dictionary[Constants.kURL] as? String,
            let checkedBy = dictionary[Constants.kCheckedBy] as? String,
            let notes = dictionary[Constants.kNotes] as? String,
            let status = dictionary[Constants.kStatus] as? String,
            let statusColor = dictionary[Constants.kStatusColor] as? String,
            let barnivoreChecked = dictionary[Constants.kBarnivoreChecked] as? Bool else { return nil }

        self.id = id
        self.companyName = companyName
        self.address = address
        self.city = city
        self.state = state
        self.postal = postal
        self.country = country
        self.phone = phone
        self.email = email
        self.url = url
        self.checkedBy = checkedBy
        self.notes = notes
        self.status = status
        self.statusColor = statusColor
        self.barnivoreChecked = barnivoreChecked
        self.alcoholType = type
    }

    // This failable initializer has all the original properties I want to get from the initial API which I'll be retrieving the information from.

    convenience init?(barnivoreDictionary: [String: AnyObject]) {
        guard
            let id = barnivoreDictionary[Constants.kID] as? Int,
            let companyName = barnivoreDictionary[Constants.kCompanyName] as? String,
            let address = barnivoreDictionary[Constants.kAddress] as? String,
            let city = barnivoreDictionary[Constants.kCity] as? String,
            let state = barnivoreDictionary[Constants.kState] as? String,
            let postal = barnivoreDictionary[Constants.kPostal] as? String,
            let country = barnivoreDictionary[Constants.kCountry] as? String,
            let phone = barnivoreDictionary[Constants.kPhone] as? String,
            let email = barnivoreDictionary[Constants.kEmail] as? String,
            let url = barnivoreDictionary[Constants.kURL] as? String,
            let checkedBy = barnivoreDictionary[Constants.kCheckedBy] as? String,
            let notes = barnivoreDictionary[Constants.kNotes] as? String,
            let status = barnivoreDictionary[Constants.kStatus] as? String,
            let statusColor = barnivoreDictionary[Constants.kStatusColor] as? String else {
                self.init(id: 0, companyName: "", address: "", city: "", state: "", postal: "", country: "", phone: "", email: "", url: "", checkedBy: "", notes: "", status: "", statusColor: "", alcoholType: alcoholType! )
                return nil
        }

        self.id = id
        self.companyName = companyName
        self.address = address
        self.city = city
        self.state = state
        self.postal = postal
        self.country = country
        self.phone = phone
        self.email = email
        self.url = url
        self.checkedBy = checkedBy
        self.notes = notes
        self.status = status
        self.statusColor = statusColor
        self.alcoholType = nil
    }

    init(id: Int, companyName: String, address: String, city: String, state: String, postal: String, country: String, phone: String, email: String, url: String, checkedBy:String, notes: String, status: String, statusColor: String, barnivoreChecked: Bool = true, alcoholType: AlcoholType) {

        self.id = id
        self.companyName = companyName
        self.address = address
        self.city = city
        self.state = state
        self.postal = postal
        self.country = country
        self.phone = phone
        self.email = email
        self.url = url
        self.checkedBy = checkedBy
        self.notes = notes
        self.status = status
        self.statusColor = statusColor
        self.identifier =  NSUUID()
        self.barnivoreChecked = barnivoreChecked
        self.alcoholType = alcoholType
    }
}

很遗憾,我收到一条错误消息:

"self" 在 self.init 调用之前使用。

如果我尝试只使用self.init(),我会收到错误:

不能在没有参数的情况下调用“Alcohol.init”。

任何帮助或建议将不胜感激。

【问题讨论】:

  • 使用 super.init(),或者(更好)覆盖 init() { super.init() }

标签: swift initialization


【解决方案1】:

在 Swift 3 中,便利构造器必须先调用同一类中的指定构造器,然后在便利构造器中尝试访问 self

我建议你把你的便利初始化器改成这样:

convenience init?(barnivoreDictionary: [String: AnyObject]) {
    guard
        let id = barnivoreDictionary[Constants.kID] as? Int,
        let companyName = barnivoreDictionary[Constants.kCompanyName] as? String,
        let address = barnivoreDictionary[Constants.kAddress] as? String,
        let city = barnivoreDictionary[Constants.kCity] as? String,
        let state = barnivoreDictionary[Constants.kState] as? String,
        let postal = barnivoreDictionary[Constants.kPostal] as? String,
        let country = barnivoreDictionary[Constants.kCountry] as? String,
        let phone = barnivoreDictionary[Constants.kPhone] as? String,
        let email = barnivoreDictionary[Constants.kEmail] as? String,
        let url = barnivoreDictionary[Constants.kURL] as? String,
        let checkedBy = barnivoreDictionary[Constants.kCheckedBy] as? String,
        let notes = barnivoreDictionary[Constants.kNotes] as? String,
        let status = barnivoreDictionary[Constants.kStatus] as? String,
        let statusColor = barnivoreDictionary[Constants.kStatusColor] as? String else {
            return nil
    }

    self.init(id: id, companyName: companyName, address: address, city: city, state: state, postal: postal, country: country, phone: phone, email: email, url: url, checkedBy: checkedBy, notes: notes, status: status, statusColor: statusColor, alcoholType: alcoholType)
}

请注意,您不需要在 guard 中调用 self.init...

【讨论】:

  • 是的,这就是解决方案。非常感谢!
猜你喜欢
  • 2021-08-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-09-26
  • 2015-06-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多