快速覆盖方法

时间:2019-06-28 06:23:51

标签: swift overriding

基本上,我目前正在将functionX添加到所有我呈现UIAlertController的地方,如下所示:

let alert = UIAlertController(title: "", message: "", preferredStyle: .alert)
let okAction = UIAlertAction(title: "ok", style: .default)
alert.addAction(okAction)
functionX(actionSheet: alert, controller: self)
self.present(alert, animated: true, completion: nil)
// or it can be
// tableviewController.present(alert, animated: true, completion: nil)

我不想每次都调用functionX,而是要覆盖当前方法并在那里调用functionX。我尝试了以下操作:

extension UIViewController {
    override func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        if (viewControllerToPresent is UIAlertController) {
            functionX(actionSheet: viewControllerToPresent, controller: /* what should this be? */ )
        }
        super.present() //error here
    }
}

这是适当的方法吗?您能帮我填写缺少的参数吗?

即:

  • 控制器应该是什么?来自第一个代码存根的selftableviewController将在覆盖当前函数中是什么?

  • 我应该如何在覆盖当前函数中调用present方法?

3 个答案:

答案 0 :(得分:4)

根据Swift guide

  

扩展可以为类型添加新功能,但不能覆盖现有功能。

因此,您实际上不应覆盖扩展名UIViewController中的现有方法。

您可以做的是添加自己的present,称为functionXAndPresent

extension UIViewController {
    func functionXAndPresent(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
        if (viewControllerToPresent is UIAlertController) {
            // to answer your second question, you should use "self" here
            functionX(actionSheet: viewControllerToPresent, controller: self)
        }
        present(viewControllerToPresent, animated: flag, completion: completion)
    }
}

您无法通过覆盖来执行此操作,因为如您所知,您最终无法真正引用“非覆盖”方法。 super.present不起作用,因为您在扩展程序中,而不是在子类中。

答案 1 :(得分:1)

您可以简单地在showAlert(with:and:) UIViewController中创建通用方法extension,并在显示functionX时调用alert,即

extension UIViewController {
    func showAlert(with title: String?, message: String?) {
        let alert = UIAlertController(title: title, message: message, preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default)
        alert.addAction(okAction)
        self.present(alert, animated: true, completion: {
            self.functionX(actionSheet: alert, controller: self)
        })
    }

    func functionX(actionSheet: UIAlertController, controller: UIViewController) {
        //your code here...
    }
}

用法:

从所需的任何控制器中调用showAlert(with:and:)方法,无论是UIViewController还是UITableViewController或其他任何方法,即

self.showAlert(with: "Alery..!!!", message: "This is a sample alert.")

答案 2 :(得分:0)

在Swift的静态扩展中重写NSObject派生类仅是为了实现Objective-C兼容性。您不能override在纯Swift声明的扩展中。可以这样考虑:如果类本身添加了覆盖,然后静态扩展添加了覆盖。链接器应链接哪个实现? super调用指的是哪种实现?在Objective-C中,此行为是未定义的,在Swift中,扩展覆盖均被忽略。

您可以做的是将重写功能从扩展名直接移到类中。