Tappostate中的Swift 2无法识别的选择器

Tappostate中的Swift 2无法识别的选择器,swift,swift2,ios9,xcode7-beta4,Swift,Swift2,Ios9,Xcode7 Beta4,我最近开始将我的应用程序升级到Swift 2.0,但我遇到了一个问题,这个问题有上百个不同的答案,所有答案似乎都与我的问题无关 (在将应用程序更新为Swift 2.0之前,这项功能已经起作用),但我还没有找到对点击手势识别器所做的任何更改 下面是我得到的全部错误: [Stocks.SidePanelViewController ProformulaTap手势]:发送到实例0x14f06ae00的无法识别的选择器 由于未捕获的异常“NSInvalidArgumentException”而终止应用程

我最近开始将我的应用程序升级到Swift 2.0,但我遇到了一个问题,这个问题有上百个不同的答案,所有答案似乎都与我的问题无关

(在将应用程序更新为Swift 2.0之前,这项功能已经起作用),但我还没有找到对点击手势识别器所做的任何更改

下面是我得到的全部错误:

[Stocks.SidePanelViewController ProformulaTap手势]:发送到实例0x14f06ae00的无法识别的选择器

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:'-[Stocks.SidePanelViewController ProformulaTap手势]:未识别的选择器已发送到实例0x14f06ae00'

***第一次抛出调用堆栈: (0x1830904d0 0x197AFF9C 0x1830971ec 0x183094188 0x182f9920c 0x188c3c58c 0x188899b50 0x18872d104 0x188c3bc30 0x1886ed28c 0x1886eb3ac 0x18872b088 0x18872a5ec 0x1886fb908 0x1886f9fac 0x183047d6c 0x183047800 0x183045500 0x182f75280 0x18e0ec0cc 0x188762df8 0x10015884 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()
    }
但是,由于它从未在控制台中打印“ProformulaTap手势”。我肯定认为错误发生在函数之前。提到选择器时出现的错误也说明了这一点

显然,自从更新到Swift 2.0后,try/catch已添加到函数中,但TapGestureRecognitizer的设置没有任何更改

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

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

最初的代码是用Swift编写的,而不是Obj-C。在苹果将代码转换为Swift 2.0的过程中添加了Trows and try

如果您能帮我解释一下为什么会突然断开,我们将不胜感激


谢谢

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

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

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

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

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
    }
}
如果您无法在
proformulatappostate
中处理错误,则必须更具创造性地将其从函数中传递出去(想想NSNotification,等等)


为了清楚起见,我在Xcode 7 beta 4中创建了一个新的单视图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项目上进行了测试,这是我在前面的回答中使用的代码)。

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

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

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

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

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
    }
}
如果您无法在
proformulatappostate
中处理错误,您将