【问题标题】:Xcode 7.3 / Swift 2: "No method declared with Objective-C selector" warningXcode 7.3 / Swift 2:“没有使用 Objective-C 选择器声明的方法”警告
【发布时间】:2016-07-09 16:13:10
【问题描述】:

我使用选择器已经有一段时间了,即使在迁移到 Swift 之后,我也能够毫无问题地使用它们。这就是我在将 Xcode 更新到 7.3 版之前在 Swift 2 上毫无问题地使用的方式:

正如用户所见,我将选择器与 NSTimer 一起使用。

这是被调用的动作:

 func Start () {

 }

正如你所见,Xcode 7.3 现在给出了一个警告“没有使用 Objective-C 选择器声明的方法”。通过单击警告,Xcode 通过添加“选择器”对代码进行快速修复,但我仍然收到相同的警告:

【问题讨论】:

    标签: swift nstimer


    【解决方案1】:

    在 Swift 4 上,我必须在 func 之前添加 @objc 以消除警告。

    这就是我用 NSTimer 调用函数的方式:

     Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(ViewController.intro), userInfo: nil, repeats: false)
    

    函数是这样声明的:

         @objc func intro () {
    
              // do your stuff here         
    
         }
    

    我还按照 Xcode 的要求更新了设置:

    没有更多警告,一切似乎都正常。

    【讨论】:

      【解决方案2】:

      从 Swift 2.2 / Xcode 7.3 开始,有一种使用选择器的新方法: Selector("funcName")改为#selector(ClassName.funcName)

      看看https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md

      tl;博士;

      Selector("Start") 替换为#selector(YOUR_CLASS.Start)

      其中 YOUR_CLASS = 给定上下文中的目标类别。

      如果你不想手动操作,Xcode默认提供了简单的修复,当你有以下情况时,点击黄色三角形(有时需要多次点击/单击),

      它会给你建议:

      如果您选择该建议,它将自动更新选择器:

      【讨论】:

      • 这样好多了,不会再因为拼写错误而崩溃
      • 不确定您的意思?在 swift 2.2 选择器被输入为字符串之前,如果输入错误,您不会收到编译器警告。
      • 值得注意的是,因为看起来这个问题可能经常被链接到,所以方法名称通常以小写字母开头,所以 func StartYOUR_CLASS.Start 应该是 func startYOUR_CLASS.start .
      • @crashoverride777:如果在两个不同的类中使用相同的方法,我需要做什么??
      • 这个方法可以传参数吗?
      【解决方案3】:

      以下两个语句都可以完美运行。上面的主要是用的。 However when the selector method is in a different ViewController the compiler warning "No method declared with Objective-C selector 'buttonHandler'" may occur.

      第二个列出的语句没有给出这个警告。

      button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)
      
      button.addTarget(parentViewController, action: #selector(MainViewController.buttonHandler), forControlEvents: .TouchUpInside)
      

      在目标视图控制器(MainViewController)中可以定义模块:

      func buttonHandler(sender:UIButton!) {
          print ("Pressed")
      }
      

      【讨论】:

      • 虽然它会发出警告,但它会起作用。刚刚在 Apple Swift 2.2 版上进行了测试。注意 ':' 是必需的。
      【解决方案4】:

      我自己的一些发现来支持文森特所说的(太长了,不能直接评论)

      不一定在不同的视图控制器中,而只是在不同的文件中,以下格式不起作用:

      button.addTarget(parentViewController, action: Selector("buttonHandler:"), forControlEvents: .TouchUpInside)

      例如,如果您在单独的文件中有扩展名,尽管对于同一个视图控制器,这种格式 Selector("buttonHandler:") 将不起作用。

      Further, when the selector is in the same file and VC, Xcode's quick-fix prompts you to have the selector include the constructor, so it would look something like this:

      #selector(MainViewController.buttonHandler(_:))

      然而这种格式只适用于选择器在同一个VC+文件中,如果是在一个单独的文件中,但是同一个VC,那么推荐的方法就行不通了,你需要使用没有构造函数的方法

      #selector(MainViewController.buttonHandler)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-07-21
        • 1970-01-01
        • 2014-03-03
        • 2013-12-16
        • 2011-01-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多