Swift希望将#selector的参数暴露给Objective-C

我有一个Swift项目,我想将一个方法附加到UIButton的轻敲事件。 我有以下代码:

class MyClass { let myButton = UIButton(frame: CGRectMake(50, 50, 100, 50)) init() { myButton.addTarget(self, #selector(self.didTap(_:)), forControlEvents: .TouchUpInside) } func didTap(sender: UIButton) { print("Tapped") } } 

XCode突出显示我的addTarget行,并说:

 Argument of '#selector' refers to a method that is not exposed to Objective-C 

如果我添加@objc前缀到我的func didTap喜欢它build议然后一切工作正常。

我是否在我的构build设置中启用了导致这种奇怪行为的东西?

PS。 我在7.3.1中得到这个行为。 但是,如果我在7.2.1中尝试这样做,它不接受#selector(method(_:))语法,而Selector("method:")正常工作。

select器是Objective-C的一个function,只能用于暴露给dynamicObj-C运行时的方法。 你不能有一个纯粹的Swift方法的select器。

如果你的类inheritance自NSObject那么它的公共方法会自动暴露给Obj-C。 由于你的类不是从NSObjectinheritance的,所以你必须使用@objc属性来表明你想让这个方法暴露给Obj-C,这样它就可以用一个Obj-Cselect器来调用。

#selector()是Swift 2.2中的新语法。 它允许编译器检查你正在尝试使用的select器实际上是否存在。 旧的语法已被弃用,并将在Swift 3.0中被删除。

如果我添加@objc前缀到我的func didTap喜欢它build议然后一切工作正常。

我是否在我的构build设置中启用了导致这种奇怪行为的东西?

不,你看到的是正常的。 select器是一个Objective-Cfunction,所以使用select器将消息发送到您的类实例。 Objective-C发送消息的唯一方法是它是否可以看到你的类或方法本身。 MyClass本身并不是从NSObject派生的,所以Objective-C看不到它。 所以如果你不想从NSObject派生它,你至less不得不通过@objc来标记方法到Objective-C。

和select器(“方法:”)工作正常

在早期版本的Swift中,编译器在这种情况下不会帮助你,所以你的代码将被编译。 但是当消息到达并且Objective-C找不到方法时,你会崩溃。 #selector语法的#selector是帮助您避免崩溃。 这就是它做的!

你必须从NSObject子类