Swift 2 个无法识别的点击手势选择器
Swift 2 unrecognized selector in tapgesture
我最近开始将我的应用程序更新到 Swift 2.0,但是我 运行 遇到了一个问题,这个问题有一百个不同的答案,none与我的问题有关。
(这在将应用程序更新到 Swift 2.0 之前有效),但我还没有找到对点击手势识别器所做的任何更改?
这是我得到的完整错误:
[Stocks.SidePanelViewController proFormulaTapGesture]: unrecognized selector sent to instance 0x14f06ae00
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Stocks.SidePanelViewController proFormulaTapGesture]: unrecognized selector sent to instance 0x14f06ae00'
*** First throw call stack:
(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: terminating with uncaught exception of type 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”。我绝对认为错误发生在函数之前。也由提到选择器的错误提示。
显然 try/catch 自更新到 Swift 2.0 以来已添加到功能中,但在 tapGestureRecognizer 的设置中没有任何更改。
我尝试删除“throws”并从函数中尝试,但问题仍然存在。我还尝试制作一个按钮而不是点击手势识别器。但我仍然遇到同样的错误,表明这可能是选择器(功能)的问题,而不是点击手势/按钮的问题。但是我应用程序中的所有其他按钮都可以正常工作吗?
我还尝试重命名 selector/function 和点击手势识别器。还是一样。
原始代码是在 Swift 中编写的,而不是 Obj-C。 throws and try 是在 Apple 代码转换为 Swift 2.0
期间添加的
如能就此问题突然崩溃提供任何帮助,我们将不胜感激。
谢谢!
问题可能是 UIKit 不知道如何调用 throws
的选择器,至少在这种情况下是这样。
请记住,UIKit 将调用此函数以响应点击操作。不习惯调用throws
的函数;显然,就 Objective-C 运行时而言,throw
必须更改方法的调用签名。除此之外,如果你的函数 proFormulaTapGesture
确实抛出了一个错误,即使 UIKit 能够捕捉到它,它会如何处理这个错误?
我不确定你在哪里添加了 do
/try
/catch
。但除非它在您的操作函数 proFormulaTapGesture
中,否则我看不出它有什么相关性。我相信你将需要在 proFormulaTapGesture
内部实现 try
/catch
错误处理,以便它有效地吞噬错误,从而使 proFormulaTapGesture
不抛出。
我刚刚自己创建了一个快速测试项目,发现 throw
ing 目标操作给出了与您遇到的相同的 "Unrecognized selector" 错误:
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]: unrecognized selector sent to instance 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 中创建了一个新的单一视图 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 项目上进行了测试,这是我之前在答案中使用的代码)。
我最近开始将我的应用程序更新到 Swift 2.0,但是我 运行 遇到了一个问题,这个问题有一百个不同的答案,none与我的问题有关。
(这在将应用程序更新到 Swift 2.0 之前有效),但我还没有找到对点击手势识别器所做的任何更改?
这是我得到的完整错误:
[Stocks.SidePanelViewController proFormulaTapGesture]: unrecognized selector sent to instance 0x14f06ae00
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Stocks.SidePanelViewController proFormulaTapGesture]: unrecognized selector sent to instance 0x14f06ae00'
*** First throw call stack: (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: terminating with uncaught exception of type 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”。我绝对认为错误发生在函数之前。也由提到选择器的错误提示。
显然 try/catch 自更新到 Swift 2.0 以来已添加到功能中,但在 tapGestureRecognizer 的设置中没有任何更改。
我尝试删除“throws”并从函数中尝试,但问题仍然存在。我还尝试制作一个按钮而不是点击手势识别器。但我仍然遇到同样的错误,表明这可能是选择器(功能)的问题,而不是点击手势/按钮的问题。但是我应用程序中的所有其他按钮都可以正常工作吗?
我还尝试重命名 selector/function 和点击手势识别器。还是一样。
原始代码是在 Swift 中编写的,而不是 Obj-C。 throws and try 是在 Apple 代码转换为 Swift 2.0
期间添加的如能就此问题突然崩溃提供任何帮助,我们将不胜感激。
谢谢!
问题可能是 UIKit 不知道如何调用 throws
的选择器,至少在这种情况下是这样。
请记住,UIKit 将调用此函数以响应点击操作。不习惯调用throws
的函数;显然,就 Objective-C 运行时而言,throw
必须更改方法的调用签名。除此之外,如果你的函数 proFormulaTapGesture
确实抛出了一个错误,即使 UIKit 能够捕捉到它,它会如何处理这个错误?
我不确定你在哪里添加了 do
/try
/catch
。但除非它在您的操作函数 proFormulaTapGesture
中,否则我看不出它有什么相关性。我相信你将需要在 proFormulaTapGesture
内部实现 try
/catch
错误处理,以便它有效地吞噬错误,从而使 proFormulaTapGesture
不抛出。
我刚刚自己创建了一个快速测试项目,发现 throw
ing 目标操作给出了与您遇到的相同的 "Unrecognized selector" 错误:
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]: unrecognized selector sent to instance 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 中创建了一个新的单一视图 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 项目上进行了测试,这是我之前在答案中使用的代码)。