【发布时间】:2017-09-05 20:13:44
【问题描述】:
所以我一直在尝试创建一个“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
}
我想用一个方便的 init 来初始化它,它接受如下字典:
{
"close" : {
"day" : 1,
"time" : "0000"
},
"open" : {
"day" : 0,
"time" : "0900"
}
}
这是我的初始化程序,最初我把繁重的工作放到了一个辅助方法中。但是,我遇到了与现在相同的错误,因此我删除了辅助方法,但错误仍在发生。不确定它认为我在哪里称呼自己。
更新:将日期格式移动到日期格式器扩展中,但错误仍然存在!不确定为什么。显示新的初始化:
我的新便利初始化:
// 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") }
}
【问题讨论】:
-
我不知道您标题中的错误,但您列出的代码并未在
else块中调用self.init。同样,如果抛出错误,您将捕获它(而不是调用self.init),而不是让它冒泡到调用者。 -
@Honey- 我确实有一个指定的初始化程序,但它需要初始化“start”和“end”。为了清楚起见,我会将其添加到问题中
-
@Kevin- 感谢您指出这一点,我不太清楚何时捕获错误以及何时让它们“冒泡”,尽管我已经做了很多阅读它。我在初始化失败时添加了一个“return nil”(作为一个可失败的初始化程序)
-
方法
upcoming_date从何而来?它与标准DateFormatter无关(当然不是因为 Swift 方法 从不 使用蛇形变量名称)。我怀疑在调用时使用self的类中声明了另一个formatter。除非您知道自己在做什么,否则不鼓励使用相同名称命名局部变量和属性。 -
@markocalvocruz 我删除了我的评论,它不是 100% 正确的。你在哪里添加
return nil?但基本上你得到这个错误的原因是,你正在访问一些属性,即你正在做self.someProperty之前你要么做self.init(...)要么return nil