斯威夫特:“无法识别的选择器发送到实例”,Xcode 9.4.1

Posted

技术标签:

【中文标题】斯威夫特:“无法识别的选择器发送到实例”,Xcode 9.4.1【英文标题】:Swift:"Unrecognized selector sent to instance", Xcode 9.4.1 【发布时间】:2018-06-19 03:29:45 【问题描述】:

谁能帮我解决这个问题?

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!")

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

我将不胜感激! 谢谢!

【问题讨论】:

使用 #selector(tapCancel) 而不是从字符串创建它 【参考方案1】:

我认为原因在于方法名称在 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() 语法,所以我试着玩了一下,结果:

(选择器不匹配编译器可以“看到”的任何方法)。

(添加“withSender”后,编译器可以匹配方法,但建议使用更好的#selector(...语法)。

正如@rmaddy 在 cmets 中指出的那样,使用较短的 #selector(doSomething) 语法(没有冒号、没有下划线、没有 self)也可以解决是否需要“withSender”的问题。

【讨论】:

你只需要#selector(tapCancel)。您不需要在sender 参数之前添加_。您需要在func tapCancel... 之前添加@objc @rmaddy 谢谢,我一到办公桌就会更新答案。【参考方案2】:

使用

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

而不是

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

并在方法tapCancel()之前添加@objc

【讨论】:

以上是关于斯威夫特:“无法识别的选择器发送到实例”,Xcode 9.4.1的主要内容,如果未能解决你的问题,请参考以下文章

无法识别的选择器发送到实例

[UICollectionViewCell imageView]:无法识别的选择器发送到实例

无法识别的选择器发送到实例

无法识别的选择器发送到数组中的实例[重复]

无法识别的选择器发送到实例 Objective-C

无法识别的选择器发送到实例