我最近开始将我的应用程序更新为Swift 2.0,但是我遇到了一个问题,在SO上有一百个不同的答案,其中没有一个似乎与我的问题有关。
(这在将应用程序更新到Swift 2.0之前有效),但我找不到任何更改手势识别器的更改?
这是我得到的完整错误:
[Stocks.SidePanelViewController proFormulaTapGesture]:无法识别的选择器发送到实例0x14f06ae00
由于未捕获的异常'NSInvalidArgumentException'终止应用程序,原因:' - [Stocks.SidePanelViewController 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的设置中没有任何改变。
我尝试删除“throws”并尝试使用该函数,但问题仍然存在。我也试过制作一个按钮而不是一个轻敲手势识别器。但我仍然得到相同的错误,暗示它可能是选择器(功能)的问题,而不是点击手势/按钮。但是我的应用程序中的所有其他按钮都可以正常工作吗?
我还尝试重命名选择器/功能和点击手势识别器。还是一样。
原始代码是用Swift编程的,而不是Obj-C。在Apple的代码转换到Swift 2.0期间添加了throws和try,
任何帮助解决为什么会突然被打破的人将不胜感激。
谢谢!
答案 0 :(得分:5)
问题可能是UIKit不知道如何调用throws
的选择器,至少在这种情况下。
请记住,UIKit将调用此功能以响应点击操作。它不习惯于调用throws
的函数;显然,就Objective-C运行时而言,throw
必须改变方法的调用签名。除此之外,如果你的函数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")
}
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项目上测试过,这是我在答案前面使用的代码)。