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。 由于你的类不是从NSObject
inheritance的,所以你必须使用@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
子类