gpt4 book ai didi

swift - Swift 中的 NSCalendar - init 可以返回 nil,但不是可选的

转载 作者:搜寻专家 更新时间:2023-10-31 08:03:33 27 4
gpt4 key购买 nike

如果 calendarName 无效,

NSCalendar(calendarIdentifier: calendarName) 可以返回 nil - 这是原始的 Objective-C 行为,并且是在 Swift 中也是如此。但是,编译器似乎认为初始化程序返回的是 NSCalendar 而不是 NSCalendar?,如下所示:

let c1 = NSCalendar(calendarIdentifier: "gregorian")// _NSCopyOnWriteCalendarWrapper
let c2 = NSCalendar(calendarIdentifier: "buddhist")// _NSCopyOnWriteCalendarWrapper

//let c3:NSCalendar = NSCalendar(calendarIdentifier: "rubbish") // run-time error
let c3:NSCalendar? = NSCalendar(calendarIdentifier: "rubbish") // nil

所以如果初始化器可以返回nil,我的理解是我应该可以做到

if let c4 = NSCalendar(calendarIdentifier: "rubbish") as? NSCalendar { 
//error: conditional downcast from 'NSCalendar' to 'NSCalendar' always succeeds
}

但是,如图所示,这是一个编译时错误。

我在这里误解了什么,我怎样才能安全地测试命名日历是否确实存在?

最佳答案

尽管看起来初始化程序应该返回一个完整的 NSCalendar 对象,但它看起来就像一个隐式可选对象(NSCalandar!)。如果您查看调试器中的对象,它会以 NSCalendar 的形式出现:

(NSCalendar) $R1 = 0x0000000000000000 { ObjectiveC.NSObject = parent is NULL }

更奇怪的是,以下代码在访问 nil NSCalendar 时不会产生任何运行时错误 - 至少对我而言:

    let x = NSCalendar(calendarIdentifier: "asdasda")
let y = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)
if (x.isDateInToday(NSDate())) {
println("x works")
}

if (y.isDateInToday(NSDate())) {
println("y works")
}
if (x == nil) {
println("x not calendar")
}

if (y == nil) {
println("y not calendar")
}

对我来说,这会输出“y works”和“x is not a calendar”。如果使用 nil 隐式可选,这在纯 Swift 中会出现运行时错误,但 pqnet 指出在 objective-c 中调用 nil 指针上的方法不会产生错误,它只是被忽略了——这似乎是在做什么。太奇怪了,但在这种情况下这样做确实是安全的:

    let x = NSCalendar(calendarIdentifier: "asdasda")
if (x != nil) {
//do what you need with the calendar
}

然而,更 Swift 的方法是使用显式可选 - 即这样做:

    let x : NSCalendar? = NSCalendar(calendarIdentifier: "asdasda")
if let cal = x {
//do what you need with the calendar as cal
}

您还可以使用隐式可选 let x : NSCalendar =... 并检查 if x != nil 如上所述 - 您的选择,有时似乎有所不同上下文导致隐式或显式可选...

编辑:

来自Xcode release notes :

Swift 不支持因返回 null 而失败的对象初始化器。 (16480364)!解决方法:如果有工厂方法,请改用它。否则,在可选中捕获结果。例如:

let url: NSURL? = NSURL(string: "not a url")

关于swift - Swift 中的 NSCalendar - init 可以返回 nil,但不是可选的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25284182/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com