简体   繁体   English

快速覆盖方法

[英]Method overriding in swift

Basically I am currently adding functionX to everywhere i present an UIAlertController as seen below: 基本上,我目前正在将functionX X添加到所有我呈现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)

Instead of calling functionX every time, I want to override a present method and call functionX there. 我不想每次都调用functionX ,而是要覆盖一个当前方法并在那里调用functionX I attempted the following: 我尝试了以下操作:

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
    }
}

Is this an appropriate approach? 这是合适的方法吗? Can you help me fill the missing parameters? 您能帮我填写缺少的参数吗?

ie: 即:

  • What should be the controller? 控制器应该是什么? What would self or tableviewController from the first code stub be in the overriding present function? 来自第一个代码存根的selftableviewController将在覆盖当前函数中是什么?

  • How should I call the present method in the overriding present function? 我应该如何在覆盖当前函数中调用present方法?

According to the Swift guide , 根据Swift指南

Extensions can add new functionality to a type, but they cannot override existing functionality. 扩展可以为类型添加新功能,但不能覆盖现有功能。

So you shouldn't really be overriding an existing method in a UIViewController in an extension. 因此,您实际上不应该在扩展的UIViewController中覆盖现有方法。

What you could do is, to add your own present , called functionXAndPresent : 您可以做的是添加您自己的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)
    }
}

You can't do this by overriding because as you have found out, you can't really refer to the "non-overridden" method at the end. 您无法通过覆盖来做到这一点,因为您已经发现,您实际上无法最终引用“非覆盖”方法。 super.present doesn't work because you are in an extension, not a subclass. super.present不起作用,因为您在扩展中,而不是子类中。

You can simply create a common method showAlert(with:and:) in a UIViewController extension and call functionX when the alert is presented, ie 您可以简单地在UIViewController extension创建一个通用方法showAlert(with:and:) ,并在出现alert时调用functionX ,即

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

Usage: 用法:

Call the showAlert(with:and:) method from whatever controller you want to, be it a UIViewController or a UITableViewController or any other, ie 从您想要的任何控制器调用showAlert(with:and:)方法,无论是UIViewController还是UITableViewController或任何其他控制器,即

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

Overrides of NSObject's derivatives in Swift's static extensions is only for Objective-C compatibility. Swift的静态扩展中对NSObject派生类的覆盖仅是为了实现Objective-C兼容性。 You cannot override in extensions of pure Swift declarations. 您不能在纯Swift声明的扩展中override Think of it in such manner that if the class itself adds an override, and then a static extension adds an override. 可以这样考虑:如果类本身添加了覆盖,然后静态扩展添加了覆盖。 Which implementation should the linker link? 链接器应链接哪个实现? And which implementation does super call refer to? super调用指的是哪种实现? In Objective-C this behavior is undefined, in Swift the extension override is ignored all together. 在Objective-C中,此行为是未定义的,在Swift中,扩展覆盖均被忽略。

What you could do instead is move the overriding function from the extension directly to the class. 相反,您可以做的是将重写功能从扩展名直接移到类中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM