Метод переопределения в Swift - PullRequest
0 голосов
/ 28 июня 2019

Обычно я добавляю 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
    }
}

Это подходящий подход? Можете ли вы помочь мне заполнить недостающие параметры?

т.е:.

  • Каким должен быть контроллер? Что будет self или tableviewController из первой заглушки кода в переопределяющей текущей функции?

  • Как мне вызвать метод present в переопределяющей настоящей функции?

Ответы [ 3 ]

4 голосов
/ 28 июня 2019

Согласно руководству Swift ,

Расширения могут добавлять новые функциональные возможности к типу, но они не могут переопределять существующие функциональные возможности.

Таквам не следует переопределять существующий метод в 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 голос
/ 28 июня 2019

Вы можете просто создать общий метод 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.")
0 голосов
/ 28 июня 2019

Переопределение производных NSObject в статических расширениях Swift только для совместимости с Objective-C. Вы не можете override в расширениях чистых объявлений Swift. Подумайте об этом так, что если сам класс добавляет переопределение, а затем статическое расширение добавляет переопределение. На какую реализацию должен ссылаться компоновщик? И к какой реализации относится super call? В Objective-C это поведение не определено, в Swift переопределение расширения игнорируется все вместе.

Вместо этого вы можете переместить переопределяющую функцию из расширения непосредственно в класс.

...