swift 中的方法重写
Method overriding in swift
基本上,我目前正在将 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 函数中调用 present
方法?
您可以简单地在 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...
}
}
用法:
从您想要的任何控制器调用 showAlert(with:and:)
方法,可以是 UIViewController
或 UITableViewController
或任何其他控制器,即
self.showAlert(with: "Alery..!!!", message: "This is a sample alert.")
根据 Swift guide,
Extensions can add new functionality to a type, but they cannot override existing functionality.
所以你真的不应该在扩展中覆盖 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)
}
}
你不能通过覆盖来做到这一点,因为正如你所发现的,你不能真正在最后引用 "non-overridden" 方法。 super.present
不起作用,因为您在扩展中,而不是子类中。
在 Swift 的静态扩展中重写 NSObject 的衍生物只是为了 Objective-C 兼容性。您不能 override
在纯 Swift 声明的扩展中。以这样的方式思考它,如果 class 本身添加了一个覆盖,然后静态扩展添加了一个覆盖。 linker link 应该采用哪种实现方式? super
调用指的是哪个实现?在 Objective-C 中,此行为未定义,在 Swift 中,扩展覆盖被一起忽略。
您可以做的是将覆盖函数从扩展直接移动到 class。
基本上,我目前正在将 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 函数中调用
present
方法?
您可以简单地在 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...
}
}
用法:
从您想要的任何控制器调用 showAlert(with:and:)
方法,可以是 UIViewController
或 UITableViewController
或任何其他控制器,即
self.showAlert(with: "Alery..!!!", message: "This is a sample alert.")
根据 Swift guide,
Extensions can add new functionality to a type, but they cannot override existing functionality.
所以你真的不应该在扩展中覆盖 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)
}
}
你不能通过覆盖来做到这一点,因为正如你所发现的,你不能真正在最后引用 "non-overridden" 方法。 super.present
不起作用,因为您在扩展中,而不是子类中。
在 Swift 的静态扩展中重写 NSObject 的衍生物只是为了 Objective-C 兼容性。您不能 override
在纯 Swift 声明的扩展中。以这样的方式思考它,如果 class 本身添加了一个覆盖,然后静态扩展添加了一个覆盖。 linker link 应该采用哪种实现方式? super
调用指的是哪个实现?在 Objective-C 中,此行为未定义,在 Swift 中,扩展覆盖被一起忽略。
您可以做的是将覆盖函数从扩展直接移动到 class。