Swift:“无法识别的选择器发送到实例”,Xcode 9.4.1

时间:2018-06-19 03:29:46

标签: swift uitapgesturerecognizer unrecognized-selector xcode9.4

任何人都可以帮我吗?

override func viewDidLoad() {
    super.viewDidLoad()
    tableView.delegate=self
    tableView.dataSource=self
    searchBar.autocorrectionType = .yes
    searchBar.delegate=self
    searchBarView.translatesAutoresizingMaskIntoConstraints=false

    let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector(("tapCancel:")))

    searchBarView.addGestureRecognizer(tap)
    tableView.addGestureRecognizer(tap)
    tableView.isUserInteractionEnabled=true
}
...
func tapCancel(sender:UITapGestureRecognizer){
    hideSearchBarView()
    isSearchon=false
    print("Tap cancel!")
}

每次点击View时,都会崩溃。 “无法识别的选择器发送到实例0x7feb85d109e0”

我将不胜感激任何帮助! 谢谢!

2 个答案:

答案 0 :(得分:2)

我认为原因在于如何在Swift和Objective-C之间映射方法名称,这是Cocoa实现和整个目标/行动机制的基础。

在您的情况下, Swift方法

@objc func tapCancel(sender:UITapGestureRecognizer)

...对应 Objective-C选择器

-tapCancelWithSender:

注意:为了使用目标/操作范例(即通过选择器调用),该方法需要声明为@objc。替代属性@IBOutlet(与Interface Builder一起使用)也支持此功能。 (给@rmaddy的帽子提示)

为了删除“withSender”部分并获得与tapCancel:匹配的选择器,您需要告诉Swift删除参数标签 sender,如下所示:

func tapCancel(_ sender:UITapGestureRecognizer) // Notice the underscore (_)

另外,根据@dan的评论,也许您可​​以使用:

#selector(self.tapCancel(_:))

或更简洁,正如(再次感谢)@rmaddy指出的那样,只是:

#selector(tapCancel)

(Xcode会尝试将其自动填充到#selector(tapCancel(_:)),但更短的语法也可以正常工作,方法名称会突出显示)

我不熟悉您使用的Selector()语法,所以我尝试了一下,看看:

enter image description here (选择器与编译器可以“看到”的任何方法都不匹配。)

enter image description here (在添加“withSender”之后,编译器可以匹配该方法,但它建议使用更好的#selector(...语法)。

正如@rmaddy在评论中指出的那样,使用较短的#selector(doSomething)语法(没有冒号,没有下划线,没有self)也消除了是否需要“withSender”或不。

答案 1 :(得分:0)

使用

let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(tapCancel))

而不是

let tap:UIGestureRecognizer = UITapGestureRecognizer(target: self, action: Selector(("tapCancel:")))

在方法@objc

之前添加tapCancel()