如果我扩展 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 {
// ....
}
Now let's say that only the MyViewController class actually needs to access the app delegate. Then you just say
extension MyViewController : AppDelegateAccesser {}
This injects appDelegate
into MyViewController but no other class. So you would just do that for each view controller that needs to access the app delegate, and no others. I think that's a totally unnecessary exercise, as opposed to your original proposed solution, but it does solve the problem of injecting code only into some classes.
NOTE: In Swift 5 it will be legal to declare that only a UIViewController subclass may adopt this protocol. You might like that.