Swift 2在tapgesture中无法识别的选择器

Mar*_*k L 0 swift ios9 swift2 xcode7-beta4

我最近开始将我的应用程序更新为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)
Run Code Online (Sandbox Code Playgroud)

这是我正在尝试运行的功能:

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()
    }
Run Code Online (Sandbox Code Playgroud)

但是因为它从不在控制台中打印"proFormulaTapGesture".我绝对认为错误发生在函数之前.提示选择器的错误也提示.

显然,自更新到Swift 2.0以来,try/catch已被添加到函数中,但在tapGestureRecognizer的设置中没有任何改变.

我尝试删除"抛出"并尝试从该功能,但问题仍然存在.我也试过制作一个按钮而不是一个轻敲手势识别器.但我仍然得到相同的错误,暗示它可能是选择器(功能)的问题,而不是点击手势/按钮.但是我的应用程序中的所有其他按钮都可以正常工作?

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

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

任何有关为什么突然被打破的帮助将不胜感激.

谢谢!

jus*_*ela 5

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

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

我不确定你在哪里添加do/ try/ catch.但除非它在你的动作功能中proFormulaTapGesture,否则我看不出它是如何相关的.我相信你需要在里面实现try/ catch错误处理proFormulaTapGesture,以便它有效地吞下错误,这样proFormulaTapGesture就不会抛出.

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

override func viewDidLoad() {
    super.viewDidLoad()

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

func didClick() throws {
    print("did click")
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

如果你无法处理内部的错误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")
    }

}
Run Code Online (Sandbox Code Playgroud)

(注意我还在OS X项目上测试过,这是我在前面的答案中使用的代码).