是否扩展UIViewController来访问app委托反模式?

问题描述 投票:2回答:2

我正在使用一个API,建议将其客户端保留在应用程序委托中并通过那里访问它。如果我扩展UIViewController以便更容易访问应用程序委托,这是否是反模式?

extension UIViewController {
    var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
}

class SomeViewController: UIViewController {
    ...
    appDelegate.someClient.someMethod()
    ...
}

反模式我的意思是,为了这个简单的方便,扩展整个UIViewController类是否过度了?总体而言,是否会对此类课程产生负面影响?每个视图控制器,即使它不访问API,现在都隐式指向应用程序委托吗?

ios cocoa-touch appdelegate object-graph
2个回答
2
投票

如果我扩展UIViewController以使其更容易访问应用程序委托,这是一种反模式吗?

extension UIViewController {
    var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    } 
}

没有;恰恰相反。需要访问应用程序委托并将其强制转换为实际类是非常常见的,以便能够访问属性或调用应用程序委托中的方法。如果这可能需要在多个位置完成,则计算属性是提供速记的标准表示法。 (没有必要为此目的使用扩展,但这样做没有任何害处,并且可能有一个符号优势;例如,扩展可以位于app委托文件中。)


在评论中,您会想到扩展UIViewController的智慧。我想你有两个需要访问应用程序委托的视图控制器,还有许多不需要访问应用程序代理的视图控制器。

现在,首先,这并没有真正改变我的答案。我无法看到它会造成什么样的伤害,或者它是如何以任何方式使反模式为所有视图控制器提供通过快捷方式访问应用程序委托的能力,即使其中许多人从未实际这样做过。所有视图控制器都有能力做很多事情,大部分事情都不会真正做到。

但是,让我们说你感觉不是这样。然后你可以在每个相关的视图控制器中明确地实现appDelegate(以违反DRY为代价)。

或者(这是很酷的部分)您可以声明协议和协议扩展,并且只有相关的视图控制器采用它。所以,这是你的AppDelegate.swift文件:

import UIKit

protocol AppDelegateAccesser {}
extension AppDelegateAccesser {
    var appDelegate: AppDelegate {
        return UIApplication.shared.delegate as! AppDelegate
    }
}

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

现在让我们说只有MyViewController类实际上需要访问app委托。然后你就说

extension MyViewController : AppDelegateAccesser {}

这将appDelegate注入MyViewController但没有其他类。因此,您只需为需要访问应用程序委托的每个视图控制器执行此操作,而不执行其他操作。我认为这是一个完全不必要的练习,而不是你原来提出的解决方案,但它确实解决了只将代码注入某些类的问题。


注意:在Swift 5中,声明只有UIViewController子类可以采用此协议是合法的。你可能会喜欢这样。


0
投票

将此函数放到AppDelegate文件中,以便您可以在整个项目中访问AppDelegate。

class func shared() -> AppDelegate {
     return UIApplication.shared.delegate as! AppDelegate
}

您可以使用:

AppDelegate.shared()
© www.soinside.com 2019 - 2024. All rights reserved.