簡體   English   中英

在調用self.init之前自己使用的iOS Swift便利初始化程序

[英]iOS Swift convenience initializer self used before self.init called

所以我一直在嘗試創建一個“Period”類,具有以下屬性:

class PTPeriod {

    // MARK: Stored Properties

    var start: Date
    var end: Date
    var place: PTPlace?


//MARK: DESIGNATED NITIALIZER
init(start: Date, end: Date, place: PTPlace? = nil) {
    self.start = start
    self.end = end
    self.place = place

}

我想用一個接受如下字典的方便初始化它:

        {
           "close" : {
              "day" : 1,
              "time" : "0000"
           },
           "open" : {
              "day" : 0,
              "time" : "0900"
           }
        }

這是我的初始化程序,最初我將繁重的工作放入輔助方法中。 但是,我得到了同樣的錯誤,所以我刪除了輔助方法,但錯誤仍在發生。 不確定它認為我在呼喚自己的地方。

更新:將日期格式移動到日期格式化程序擴展名,但錯誤仍然存​​在! 不確定為什么。 新的init顯示:

我新的Convenience init:

// MARK: Convenience init for initializing periods pulled from Google Place API
convenience init?(placeData: [String:Any], place: PTPlace? = nil) throws {
    var start: Date? = nil
    var end: Date? = nil
    var formatter = DateFormatter()

    do {
        for (key, value) in placeData {
            let period = value as! [String: Any]
            if (key == "open") {
                start = try formatter.upcoming_date(with: period)
            } else if (key == "close") {
                end = try formatter.upcoming_date(with: period)
            } else {
                break
            }
        }
        if (start != nil && end != nil) { self.init(start: start!, end: end!, place: place) }
        else { print("we f'd up") }

    }

    catch { print(error.localizedDescription) }
}

這是我的DateFormatter.upcoming_date方法:

   func upcoming_date(with googlePlacePeriod: [String: Any]) throws -> Date? {
    if let day = googlePlacePeriod["day"] as? Int {
        if (day < 0) || (day > 6) { throw SerializationError.invalid("day", day) } // throw an error if day is not between 0-6
        if let time = googlePlacePeriod["time"] as? String {
            if time.characters.count != 4 { throw SerializationError.invalid("time", time) } // throw an error if time is not 4 char long
            var upcoming_date: Date
            let gregorian = Calendar(identifier: .gregorian)

            let current_day_of_week = Date().getDayOfWeekInt()
            let dayOfPeriod = day + 1

            ///TRUST THAT THIS WORKS... NO JODAS
            var distance = dayOfPeriod - current_day_of_week // inverse = false

            if (dayOfPeriod < current_day_of_week) {
                switch distance {
                case -1: distance = 6
                case -2: distance = 5
                case -3: distance = 4
                case -4: distance = 3
                case -5: distance = 2
                case -6: distance = 1
                default: break
                }
            }
            /** time example: "1535" translates into 3:35PM
             first two characters in string are "hour" (15)
             last two characters in string are "minute(35)
             **/

            let hour = Int(time.substring(to: time.index(time.startIndex, offsetBy: 2)))!
            let minute = Int(time.substring(from: time.index(time.endIndex, offsetBy: -2)))


            upcoming_date = Date().fastForward(amount: distance, unit: "days", inverse: false)!
            var components = gregorian.dateComponents([.year, .month, .day, .hour, .minute, .second], from: upcoming_date)
            components.hour = hour
            components.minute = minute
            upcoming_date = gregorian.date(from: components)!
            return upcoming_date
        }
        else { throw SerializationError.missing("time") }
    }
    else { throw SerializationError.missing("day") }
}

你有一個可用的初始化程序,所以如果它失敗了,你必須return nil讓它知道它失敗了:

if (start != nil && end != nil) { 
    self.init(start: start!, end: end!, place: place) }
} else { 
    print("we f'd up") 
    return nil
}

此外,在您do - catch ,你需要或者

  • catch塊中重新throw錯誤

     catch { print(error.localizedDescription) throw error } 
  • 完全消除do - catch塊; 要么

  • return nil

     catch { print(error.localizedDescription) return nil } 

    如果你這樣做,你可能不會將這個可用的初始化程序定義為throws因為你不再拋出的初始化程序。


鑒於你不太可能對拋出的錯誤做任何有意義的事情,我只是讓它成為一個不拋出的可用的初始化器:

convenience init?(placeData: [String: Any], place: PTPlace? = nil) {
    var start: Date?
    var end: Date?
    let formatter = DateFormatter()

    for (key, value) in placeData {
        let period = value as! [String: Any]
        if key == "open" {
            start = try? formatter.upcoming_date(with: period)
        } else if key == "close" {
            end = try? formatter.upcoming_date(with: period)
        } else {
            break  // I'm not sure why you're doing this; it seems extremely imprudent (esp since dictionaries are not ordered)
        }
    }

    if let start = start, let end = end {
        self.init(start: start, end: end, place: place)
    } else {
        print("either start or end were not found")
        return nil
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM