【问题标题】:Initializing NSCalendar with forced unwrapping使用强制展开初始化 NSCalendar
【发布时间】:2016-04-24 20:36:43
【问题描述】:

是否可以假设以下内容适用于所有设备?

let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!

我不是应用本地化(或其他任何事情)方面的专家,所以我不确定公历是否可以在每台设备上使用。应用程序使用这个日历的方式不是面向用户的,所以我并不关心用户使用的是哪个日历,我只是想确保上述初始化始终有效。

【问题讨论】:

  • 使用guard let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) else { return }有什么问题
  • 如果给定的方法返回一个可选项,那么您应该始终假设它可以返回 nil。即使它现在不返回 nil,它也可能在未来的更新中返回。围绕如何定义方法来设计代码,而不是猜测它们的内部实现总是更好的方法。如果您的应用无法从给定的可选项为零恢复,最好自己处理这种情况,允许您打印自己的错误消息或抛出错误等。这将使您更容易调试。
  • 也许苹果只是没有重写这个初始化器来返回非可选值,也许有时它真的返回nil。我认为如果您的应用在没有日历的情况下无法继续,使用强制展开是正常的。
  • @TimSim 你可以在从保护语句返回之前做任何你想做的事情,以防万一失败
  • @LeoDabus 但是如果有失败的可能性(并且可选的返回值表明存在),我必须重新设计我的应用程序的很大一部分以假设某些设备不知道有一周 7 天或一年 12 个月。但是,如果仅仅因为calendarIdentifier 是一个字符串而存在该可选值,并且如果我使用定义的NSCalendarIdentifierGregorian 常量就不会失败呢?

标签: ios swift localization nscalendar


【解决方案1】:

在编程中没有什么是 100% 安全的,尤其是在处理隐藏实现的 SDK 时。我回答了关于常量NSNotFoundhere 的类似问题。

NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)! 安全吗?理想情况下,如果 Apple 选择不更改他们的 SDK,或者他们提供了 NSCalendar 初始化程序的无错误实现。就防御性编码而言,您有两种选择。

按照 Leo Dabus 在 cmets 中的建议,将代码包装在 guard 中:

guard let cal = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian) else { return }

为了面向未来,Apple 可能会更改 NSCalendarIdentifier 常量(如 NSNotFound 所示)。为了增加安全性,请检查常量的内存位置:

if let str: String = NSCalendarIdentifierGregorian {
    if let _: UnsafePointer<Void> = unsafeAddressOf(str) {
        // NSCalendarIdentifierGregorian is defined on your platform
    }
}

在 Objective-C 中更简洁一些:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wtautological-compare"
BOOL found = (&NSCalendarIdentifierGregorian != NULL);
#pragma clang diagnostic pop
if (found) {
    // safe
}

我不为 Apple 工作,不能保证任何基础课程的可用性。

【讨论】:

  • 谢谢,但问题不在于如果返回 nil 应用程序会崩溃(我知道如何guard 代码所以它不会崩溃),而是我将不得不重新设计一些如果不能在所有设备上实例化公历,则应用程序的重要功能。我可能把这个问题用错了。应该是 Gregorian NSCalendar 是否可以在所有设备上实例化?
  • 我可以设置全局公历吗?我的应用程序很旧,我有一个大项目.. 我用过很多地方的日历.. 是否可以使用 swizzling 或其他方法。
猜你喜欢
  • 2020-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多