'#selector'的参数不是指初始值设定项或方法 [英] Argument of '#selector' does not refer to an initializer or method

查看:203
本文介绍了'#selector'的参数不是指初始值设定项或方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在委托中有一个名为 selectionDidFinish(controller:)的方法来解除委托给出的viewController。提交的控制器采用我的可解除的协议,有一个 UIBarButtonItem ,附加一个应该调用 selectionDidFinish(controller :) 方法,但是它给了我'#selector'的参数'没有'引用'初始化器或方法错误。

I have a method called selectionDidFinish(controller:) in a delegate to dismiss the viewController the delegate presented. The presented controller, which adopts my Dismissable protocol, has a UIBarButtonItem with an action attached to it that should call the selectionDidFinish(controller:) method but it's giving me the "Argument of '#selector' does not 'refer' to an initializer or method" error.

错误在于此 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 (个体))

I've confirmed that the dismissalDelegate is getting set properly to FormulasTableViewController so I can't understand why it can't see dismissalDelegate?.selectionDidFinish(self)).

我提交的 UIViewController 的相关代码是:

The relevant code of my presenting UIViewController is:

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

我已经做过各种关于如何使用<$ c $的研究c> #selector 我觉得这篇文章全部都是答案,但事实并非如此。

I've done all kinds of research on how to use #selector and I thought this post had all the answers, but it doesn't.

我已经尝试过这个可以忽略的协议,有或没有将它暴露给 @objc

I've tried this Dismissable protocol with and without exposing it to @objc:

@objc protocol Dismissable: class {
    weak var dismissalDelegate: DismissalDelegate? {
        get set }
    }

我也尝试过我的DismissalDelegate协议:

And I've also tried it with my DismissalDelegate protocol:

@objc protocol DismissalDelegate : class {
    func selectionDidFinish(controller: UIViewController)
}

extension DismissalDelegate where Self: UIViewController {
    func selectionDidFinish(viewController: UIViewController) {
    self.dismissViewControllerAnimated(true, completion: nil)
    }
}

我无法将我的协议扩展名暴露给 @objc - 这就是为什么这不起作用?我的 #selector 真的是问题吗?它与我的协议有关吗?

I can't expose my protocol extension to @objc - is that why this doesn't work? Is my #selector really the problem here? Does it have something to do with my protocols?

编辑:最后修复

根据接受的答案,我添加了一个解雇的功能:

Based on the accepted answer, I added a function to do the dismissal:

func dismiss() {
    dismissalDelegate?.selectionDidFinish(self)
}

然后像这样调用选择器:

and then called the selector like this:

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Done", style: .Plain, target: self, action: #selector(dismiss))


推荐答案

你不能拥有行动参数指定任意表达式。它需要调用特定的选择器 - 该类中的类和函数。

You can't have the action parameter specify an arbitrary expression. It needs to invoke a specific selector - a class and function in that class.

您需要在类中创建一个调用委托方法的函数:

You will need to create a function in your class that invokes the delegate method:

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

这篇关于'#selector'的参数不是指初始值设定项或方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆