“#selector”的参数未引用初始化程序或方法
Argument of '#selector' does not refer to an initializer or method
我在委托中有一个名为 selectionDidFinish(controller:)
的方法来关闭委托提出的 viewController。呈现的控制器采用我的 Dismissable
协议,有一个 UIBarButtonItem
附加了一个应该调用 selectionDidFinish(controller:)
方法的操作,但它给了我 "Argument of '#selector' does not 'refer' to an initializer or method" 错误。
错误在此呈现UIViewController
:
class FormulaInfoViewController: UIViewController, Dismissable {
weak var dismissalDelegate: DismissalDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Xcode doesn't like this selector
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(dismissalDelegate?.selectionDidFinish(self)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我已经确认 dismissalDelegate
已正确设置为 FormulasTableViewController
,所以我不明白为什么它看不到 dismissalDelegate?.selectionDidFinish(self))
。
我的呈现UIViewController
的相关代码是:
class FormulasTableViewController: UITableViewController, DismissalDelegate {
let formulas: [CalculationFormula] = [
CalculationFormula.epley,
CalculationFormula.baechle,
CalculationFormula.brzychi,
CalculationFormula.lander,
CalculationFormula.lombardi,
CalculationFormula.mayhewEtAl,
CalculationFormula.oConnerEtAl]
override func viewDidLoad() {
super.viewDidLoad()
let liftInfoImage = UIImage(named: "info_icon")
let liftInfoButton = UIBarButtonItem(image: liftInfoImage, style: .Plain, target: self, action: #selector(self.segueToFormulaInfo(_:)))
self.navigationItem.rightBarButtonItem = liftInfoButton
}
func selectionDidFinish(controller: UIViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let nav = segue.destinationViewController as! UINavigationController
let vc = nav.topViewController as! Dismissable
vc.dismissalDelegate = self
}
func segueToFormulaInfo(sender: UIButton) {
performSegueWithIdentifier("segueToFormulaInfo", sender: self)
}
}
我对如何使用 #selector
进行了各种研究,我认为 this post 有所有答案,但事实并非如此。
我已经尝试过这个 Dismissable 协议,无论是否将其暴露给 @objc
:
@objc protocol Dismissable: class {
weak var dismissalDelegate: DismissalDelegate? {
get set }
}
我也用我的 DismissalDelegate 协议试过了:
@objc protocol DismissalDelegate : class {
func selectionDidFinish(controller: UIViewController)
}
extension DismissalDelegate where Self: UIViewController {
func selectionDidFinish(viewController: UIViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
我无法将我的协议扩展公开给 @objc
- 这就是为什么它不起作用的原因吗?我的 #selector
真的是这里的问题吗?它与我的协议有关吗?
编辑:最终修复
基于接受的答案,我添加了一个函数来执行解雇:
func dismiss() {
dismissalDelegate?.selectionDidFinish(self)
}
然后像这样调用选择器:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(dismiss))
您不能让 action
参数指定任意表达式。它需要调用一个特定的选择器——一个 class 并在 class 中运行。
您需要在 class 中创建一个调用委托方法的函数:
class FormulaInfoViewController: UIViewController, Dismissable {
weak var dismissalDelegate: DismissalDelegate?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(FormulaInfoViewController.selectionDidFinish)
}
@objc func selectionDidFinish() {
self.dismissalDelegate?.selectionDidFinish(self)
}
}
我在委托中有一个名为 selectionDidFinish(controller:)
的方法来关闭委托提出的 viewController。呈现的控制器采用我的 Dismissable
协议,有一个 UIBarButtonItem
附加了一个应该调用 selectionDidFinish(controller:)
方法的操作,但它给了我 "Argument of '#selector' does not 'refer' to an initializer or method" 错误。
错误在此呈现UIViewController
:
class FormulaInfoViewController: UIViewController, Dismissable {
weak var dismissalDelegate: DismissalDelegate?
override func viewDidLoad() {
super.viewDidLoad()
// Xcode doesn't like this selector
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(dismissalDelegate?.selectionDidFinish(self)))
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
我已经确认 dismissalDelegate
已正确设置为 FormulasTableViewController
,所以我不明白为什么它看不到 dismissalDelegate?.selectionDidFinish(self))
。
我的呈现UIViewController
的相关代码是:
class FormulasTableViewController: UITableViewController, DismissalDelegate {
let formulas: [CalculationFormula] = [
CalculationFormula.epley,
CalculationFormula.baechle,
CalculationFormula.brzychi,
CalculationFormula.lander,
CalculationFormula.lombardi,
CalculationFormula.mayhewEtAl,
CalculationFormula.oConnerEtAl]
override func viewDidLoad() {
super.viewDidLoad()
let liftInfoImage = UIImage(named: "info_icon")
let liftInfoButton = UIBarButtonItem(image: liftInfoImage, style: .Plain, target: self, action: #selector(self.segueToFormulaInfo(_:)))
self.navigationItem.rightBarButtonItem = liftInfoButton
}
func selectionDidFinish(controller: UIViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let nav = segue.destinationViewController as! UINavigationController
let vc = nav.topViewController as! Dismissable
vc.dismissalDelegate = self
}
func segueToFormulaInfo(sender: UIButton) {
performSegueWithIdentifier("segueToFormulaInfo", sender: self)
}
}
我对如何使用 #selector
进行了各种研究,我认为 this post 有所有答案,但事实并非如此。
我已经尝试过这个 Dismissable 协议,无论是否将其暴露给 @objc
:
@objc protocol Dismissable: class {
weak var dismissalDelegate: DismissalDelegate? {
get set }
}
我也用我的 DismissalDelegate 协议试过了:
@objc protocol DismissalDelegate : class {
func selectionDidFinish(controller: UIViewController)
}
extension DismissalDelegate where Self: UIViewController {
func selectionDidFinish(viewController: UIViewController) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
我无法将我的协议扩展公开给 @objc
- 这就是为什么它不起作用的原因吗?我的 #selector
真的是这里的问题吗?它与我的协议有关吗?
编辑:最终修复
基于接受的答案,我添加了一个函数来执行解雇:
func dismiss() {
dismissalDelegate?.selectionDidFinish(self)
}
然后像这样调用选择器:
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(dismiss))
您不能让 action
参数指定任意表达式。它需要调用一个特定的选择器——一个 class 并在 class 中运行。
您需要在 class 中创建一个调用委托方法的函数:
class FormulaInfoViewController: UIViewController, Dismissable {
weak var dismissalDelegate: DismissalDelegate?
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(FormulaInfoViewController.selectionDidFinish)
}
@objc func selectionDidFinish() {
self.dismissalDelegate?.selectionDidFinish(self)
}
}