2

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

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

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

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

4

2 回答 2

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 {
    // ....
}

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.

于 2019-02-05T17:47:02.750 回答
0

Put this function to AppDelegate file so you can access AppDelegate throughout your project.

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

You can use like :

AppDelegate.shared()
于 2019-04-17T08:07:19.867 回答