在Swift中使用选择器的正确方法

jos*_*das 12 selector ios swift

我正在以编程方式创建视图,并添加一个函数,以便操作响应UIControlEvents.TouchUpInside事件:

button.addTarget(self, action: action, forControlEvents: 
UIControlEvents.TouchUpInside)
Run Code Online (Sandbox Code Playgroud)

因此,通过进入文档,我已将此操作添加为选择器:

#selector(ViewController.onRegularClick)
Run Code Online (Sandbox Code Playgroud)

然后XCode抱怨:

#selector的参数是指未向Objective-C公开的方法

所以我必须设置处理函数:

@objc func onRegularClick(sender: UIButton)
Run Code Online (Sandbox Code Playgroud)

有人可以通过引导我阅读文档,或者甚至给出简短的解释,将这个菜鸟放在正确的方向:

  1. 为什么我不能再简单地将函数名称String传递给动作?
  2. 如何按照Swift方式实现这个?使用Selector类?
  3. 为什么我们需要传递@objc关键字以及它如何影响函数?

谢谢!

Avt*_*Avt 14

  1. 为什么我不能再简单地将函数名称String传递给动作?

不推荐使用字符串作为选择器,现在应该编写#selector(methodName)而不是"methodName".如果methodName()方法不存在,您将收到编译错误 - 在编译时消除了另一类错误.字符串无法实现这一点.

  1. 如何按照Swift方式实现这个?使用Selector类?

你是以正确的方式做到的:

button.addTarget(self, action: #selector(ClassName.methodName(_:)), forControlEvents: UIControlEvents.TouchUpInside)

  1. 为什么我们需要传递@objc关键字以及它如何影响函数?

在Swift中,通常的方法是在编译时绑定方法的调用和方法的主体(比如C和C++).Objective C在运行时执行此操作.所以在Objective C中你可以做一些Swift中无法实现的事情 - 例如,可以在运行时交换方法的实现(它被称为方法调配).Cocoa被设计为使用Objective C方法,这就是为什么你必须通知编译器你的Swift方法应该编译类似ObjectiveC的样式.如果你的类继承了NSObject,即使没有@objc关键字,它也会被编译成类似ObjC的样式.


Luc*_*rti 8

  1. 嗯,它被称为进化
  2. 当方法中有一些参数时,您应该将选择器声明为:

    let selector = #selector(YourClass.selector(_:))
    
    Run Code Online (Sandbox Code Playgroud)

    #selector(selector(_:))当选择器与调用者的同一类时,才能键入._:表示接受一个参数.因此,如果它接受更多参数,您应该执行以下操作:(_:, _:)等等.

  3. 我发现@objc仅当函数声明为private或对象不从NSObject继承时才需要