【问题标题】:Can 'downcasting' to AppDelegate ever fail?AppDelegate 的“向下转换”会失败吗?
【发布时间】:2017-10-24 12:10:23
【问题描述】:

使用 CoreData 时,我们需要访问通过 AppDelegate 提供的共享存储。要获得对 AppDelegate 的引用,我们可以通过以下方式获得它:

guard let appDelegate = UIApplication.shared.delegate as? AppDelegate 
else {
        return
    }

为什么我们在向下转换到 Appdelegate 时必须如此安全?沮丧会因某种原因而失败吗?如果是,为什么?

我环顾四周,找不到我们写这段代码的原因,想知道我为什么写东西会有帮助!

【问题讨论】:

    标签: ios swift cocoa-touch


    【解决方案1】:

    可选的向下转换到AppDelegate(实际上是表示应用程序委托类的类)永远不会失败,因为如果应用程序委托类丢失,应用程序甚至都不会启动。

    你可以100%安全地写

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    

    许多人患有感叹号恐惧症?并认为所有感叹号都是邪恶的,你总是必须guard任何可选的。这是错误的。世界不仅是黑白的。在很多情况下,强制解包一个可选项是安全的,就像在这种特殊情况下一样。

    【讨论】:

    • 非常感谢瓦迪安。这非常有帮助,相信我。我也经常避免使用强制展开,但很高兴知道它不时使用是安全的。
    • 自 2019 年起,它不再是恐惧症,他们禁止它并出现错误:强制施法违规:应避免强制施法。 (force_cast)
    • @Async- 他们是谁?这个错误发生在哪里?
    • @vadian 是的,抱歉,在我的情况下实际上是 SwiftLint,我将它与 xcode 错误混淆了。
    【解决方案2】:

    @UIApplicationMain 属性添加到类中

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate { ... }
    

    相当于在“main.swift”中调用UIApplicationMain() 使用“AppDelegate”作为实例化应用程序委托的类的名称:

    UIApplicationMain(
        CommandLine.argc,
        UnsafeMutableRawPointer(CommandLine.unsafeArgv)
            .bindMemory(
                to: UnsafeMutablePointer<Int8>.self,
                capacity: Int(CommandLine.argc)),
        nil,
        NSStringFromClass(AppDelegate.self)
    )
    

    (比较例如What does "@UIApplicationMain" mean?Subclass UIApplication with Swift)。

    使用任一方法,都会创建AppDelegate 类的实例 并作为委托传递给应用程序对象。所以是的,

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    

    是安全的。

    但请注意,类名“AppDelegate”并没有什么特别之处,这只是约定。您可以定义应用程序 委托为

    @UIApplicationMain
    class MyFantasticAppDelegate: UIResponder, UIApplicationDelegate { ... }
    

    在这种情况下当然是

    let appDelegate = UIApplication.shared.delegate as! MyFantasticAppDelegate
    

    所以准确的说法是

    UIApplication.shared.delegate 转换为定义为应用程序委托的类的类型不会失败。

    按照惯例,该类型是AppDelegate,但不一定是。

    【讨论】:

    • 谢谢 Martin,我会阅读这两个链接 - 这非常有帮助!
    【解决方案3】:

    我不同意强制展开向下转换到 AppDelegate 永远不会失败的观点。这不是真的。因为“AppDelegate”可能是您代表的错误类型。例如,当应用程序使用 RxAppState 框架时,我遇到了它。它有一个 AppDelegate 扩展,它返回“RxAppState.RxApplicationDelegateProxy”类作为委托。所以要时刻小心。

    【讨论】:

    • 是的,但这是一个设计错误,可以立即修复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-11-26
    • 1970-01-01
    • 2014-10-18
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 2019-03-27
    相关资源
    最近更新 更多