我正在使用一个API,建议将其客户端保留在应用程序委托中并从那里访问它。如果我扩展了UIViewController
以使其更易于访问应用程序委托,这是否是反模式?
extension UIViewController {
var appDelegate: AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
}
class SomeViewController: UIViewController {
...
appDelegate.someClient.someMethod()
...
}
通过反模式,我的意思是,为这种简单的方便而扩展整个UIViewController
类是否为时过早?像这样的扩展类,总体上是否有负面影响?每个视图控制器即使不访问API也会隐式指向应用程序委托吗?
答案 0 :(得分:2)
如果我扩展了UIViewController以使其更易于访问该应用程序 代表,这是反模式吗?
extension UIViewController { var appDelegate: AppDelegate { return UIApplication.shared.delegate as! AppDelegate } }
否;恰恰相反。通常需要访问应用程序委托并将其强制转换为它的实际类,以便能够访问属性或在应用程序委托中调用方法。如果这可能需要在多个地方完成,则计算属性是提供速记的标准符号。 (无需为此目的使用扩展名,但这样做没有害处,并且可能会有符号上的优势;例如,该扩展名可以位于应用程序委托文件中。)
在注释中,您对扩展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类需要访问应用程序委托。那你就说
extension MyViewController : AppDelegateAccesser {}
这会将appDelegate
注入MyViewController,但不会注入其他类。因此,您只需要为每个需要访问应用程序委托的视图控制器执行此操作,而无需执行其他操作。与您最初提出的解决方案相比,我认为这是完全不必要的练习,但是它确实解决了仅将代码注入某些类的问题。
注意:在Swift 5中,声明仅UIViewController子类可以采用此协议是合法的。您可能会喜欢。
答案 1 :(得分:0)
将此功能放到AppDelegate文件中,以便您可以在整个项目中访问AppDelegate。
class func shared() -> AppDelegate {
return UIApplication.shared.delegate as! AppDelegate
}
您可以像这样使用:
AppDelegate.shared()