【问题标题】:Swift 2 unrecognized selector in tapgestureTapgesture中的Swift 2无法识别的选择器
【发布时间】:2015-10-17 03:25:52
【问题描述】:

我最近开始将我的应用程序更新到 Swift 2.0,但我遇到了一个问题,在 SO 上有一百个不同的答案,但似乎都与我的问题无关。

(这在将应用程序更新到 Swift 2.0 之前有效),但我无法找到对点击手势识别器所做的任何更改?

这是我得到的完整错误:

[Stocks.Sid​​ePanelViewController proFormulaTapGesture]:无法识别的选择器发送到实例 0x14f06ae00

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[Stocks.Sid​​ePanelViewController proFormulaTapGesture]:无法识别的选择器发送到实例 0x14f06ae00”

*** 首先抛出调用堆栈: (0x1830904d0 0x197afff9c 0x1830971ec 0x183094188 0x182f9920c 0x188c3c58c 0x188899b50 0x18872d104 0x188c3bc30 0x1886ed28c 0x1886eb3ac 0x18872b088 0x18872a5ec 0x1886fb908 0x1886f9fac 0x183047d6c 0x183047800 0x183045500 0x182f75280 0x18e0ec0cc 0x188762df8 0x100158184 0x1983428b8) libc++abi.dylib:以 NSException 类型的未捕获异常终止

这是一个简单的点击手势。但它似乎不再识别选择器了。

这是我用来设置识别器的代码:

let proFormulaTap = UITapGestureRecognizer()

proFormulaTap.addTarget(self, action:"proFormulaTapGesture")
proFormulaView.addGestureRecognizer(proFormulaTap)

这是我要运行的函数:

func proFormulaTapGesture() throws {
        print("proFormulaTapGesture")
        selectView(proFormulaView)
        selectedMenuItem = 0
        Formula = 1
        menuTabBarController.selectedIndex = 0
        navigationController?.navigationBar.topItem!.title = "BASIC FORMULA"
        try (menuTabBarController.viewControllers as! [SuggestionsViewController])[0].loadSuggestions()
    }

但是,因为它从不在控制台中打印“proFormulaTapGesture”。我绝对认为错误发生在函数之前。提到选择器的错误也暗示了这一点。

很明显,自从更新到 Swift 2.0 后,函数中已经添加了 try/catch,但是在 tapGestureRecognizer 的设置中没有任何改变。

我尝试删除“抛出”并尝试从函数中,但问题仍然存在。我还尝试制作一个按钮而不是点击手势识别器。但是我仍然遇到同样的错误,这表明它可能是选择器(功能)而不是点击手势/按钮的问题。但是我的应用程序中的所有其他按钮都可以正常工作吗?

我还尝试重命名选择器/功能和点击手势识别器。还是一样。

原始代码是用 Swift 编写的,而不是 Obj-C。 throws 和 try 是在 Apple 代码转换为 Swift 2.0 期间添加的

任何帮助解决为什么突然被破坏将不胜感激。

谢谢!

【问题讨论】:

  • 您是否只是尝试评论该 try 语句并删除该“抛出” - 只是为了检查是否是导致问题的原因?
  • @nshebbar 我刚试过,还是一样的错误。不过还是谢谢你的建议!真的很感激!
  • 嗯,好的,也试试改函数名。
  • @nshebbar 我刚刚更新了我的帖子,并尝试修复它。是的:(
  • 尝试完全限定的函数,该函数也接受gestureRecogniser作为参数:func proFormulaTapGesture(recognizer: UITapGestureRecognizer) throws。并匹配 - proFormulaTap.addTarget(self, action:"proFormulaTapGesture:")

标签: swift swift2 ios9 xcode7-beta4


【解决方案1】:

问题可能是 UIKit 不知道如何调用 throws 的选择器,至少在这种情况下是这样。

请记住,UIKit 将调用此函数来响应点击操作。不习惯调用throws的函数;显然,就 Objective-C 运行时而言,throw 必须更改方法的调用签名。除此之外,如果你的函数proFormulaTapGesture 确实抛出了一个错误,那么即使 UIKit 可以捕获它,它会如何处理该错误?

我不确定你在哪里添加了do/try/catch。但除非它在您的操作函数proFormulaTapGesture 中,否则我看不出它有什么相关性。我相信您需要在proFormulaTapGesture 内部实现try/catch 错误处理,以便它有效地吞下错误,使proFormulaTapGesture 不会抛出。

我自己刚刚创建了一个快速测试项目,发现throwing 目标操作给出了与您相同的“无法识别的选择器”错误:

override func viewDidLoad() {
    super.viewDidLoad()

    self.tapper = NSClickGestureRecognizer(target: self, action: "didClick")
    self.view.addGestureRecognizer(self.tapper!)
}

func didClick() throws {
    print("did click")
}

2015-07-27 00:16:43.260 Test1[71047:54227175] -[Test1.ViewController didClick]:无法识别的选择器发送到实例 0x6000000c5010

...

我相信您需要重新编写代码以在操作函数内部处理错误,以便它不会抛出 - 像这样:

func proFormulaTapGesture() {
    print("proFormulaTapGesture")
    selectView(proFormulaView)
    selectedMenuItem = 0
    Formula = 1
    menuTabBarController.selectedIndex = 0
    navigationController?.navigationBar.topItem!.title = "BASIC FORMULA"
    do {
        try (menuTabBarController.viewControllers as! [SuggestionsViewController])[0].loadSuggestions()
    } catch {
        // Handle the error here somehow
    }
}

如果您无法处理 proFormulaTapGesture 中的错误,则必须更有创意地将其从函数中传递出去(想想 NSNotification 等...)。


明确地说,我在 Xcode 7 beta 4 中创建了一个新的 Single View iOS 应用程序,并将这个确切的代码用作我的 ViewController。没有其他变化。该应用程序在 iOS 模拟器中编译并运行良好。

@robertvojta 还指出,如果下面的didTap 标记为private,则还需要@objc 以避免动态调度崩溃。

import UIKit

class ViewController: UIViewController {

    var tapper: UITapGestureRecognizer?

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tapper = UITapGestureRecognizer(target: self, action: "didTap")
        self.view.addGestureRecognizer(self.tapper!)
    }

    func didTap() {
        print("did Tap")
    }

}

(注意我还在 OS X 项目上进行了测试,这是我之前在答案中使用的代码)。

【讨论】:

  • 我不是 100% 确定,我相信,... 你测试过你的代码吗?你必须使用@objc 否则你仍然会得到Unrecognized selector ...
  • 我试试这个,但正如帖子中提到的,我已经尝试过制作一个只包含打印的简单函数,它没有抛出。它仍然没有工作。但我会再试一次以确保:) 感谢您的回答。
  • 是的,您的编辑仍然出现同样的错误。
  • 我想通了。尽管我的最后一个错误,这个答案是正确的。在我清理项目后,删除了旧的日志文件等。重新启动 Xcode 并再次运行它,这工作正常。 :) 非常感谢!
  • @user2194039 删除了我的答案。为了使您的答案更好,只需添加有关 @objc 的注释,当方法是私有的时需要它(这些默认情况下不会暴露给 ObjC)。没有@objcprivate func didTap() 将无法工作。
猜你喜欢
  • 1970-01-01
  • 2019-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-16
  • 2018-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多