子类中的Swift #selector

时间:2016-04-19 22:33:25

标签: ios xcode swift

我更新XCode后,现在可以为iOS 9.3构建代码,我有很多关于更新语法以符合即将到来的Swift version 3的警告。

许多警告都是Selector,现在我使用的是这样的:

class Foo {

    func registerPan() {
        let recognizer = UIPanGestureRecognizer(target: self, action: Selector("handlePan:"))
        //do something with recognizer
    }

    func handlePan(recognizer:UIPanGestureRecognizer) {
        //handle pan gesture
    }
}

class Bar: Foo {

    override func handlePan(recognizer:UIPanGestureRecognizer) {
        //overriding handle pan gesture
    }
}

因此FooBar的实例有自己的方法来处理平移手势。 Xcode建议我更改使用选择器的方法,以使用#selector expression。编辑器自动建议的更改是:

#selector(Foo.handlePan(_:))

这是我的问题。在以前的版本中,为基类和子类调用了特定的实现。现在,即使Foo类的实例(BarBar继承registerPan函数),也会调用Foo的函数。这是对的吗?

可能XCode静态分析并不关心这里的继承。我考虑将这些选择器更改为:

#selector(self.handlePan(_:))

所以任何类的实例都会调用自己的实现,但我想确定它是不是一个好主意。

2 个答案:

答案 0 :(得分:0)

正如Apple医生所说:

  

选择器表达式允许您访问用于引用a的选择器   Objective-C中的方法。

#selector(method name)
  

方法名称必须是对可用方法的引用   Objective-C运行时。选择器表达式的值是   选择器类型的实例。例如:

class SomeClass: NSObject {
    @objc(doSomethingWithInt:)
    func doSomething(x: Int) { }
}
let x = SomeClass()
let selector = #selector(x.doSomething(_:))
  

..因为选择器是在编译时创建的,而不是在运行时创建的   编译器可以检查方法是否存在以及方法是否存在   暴露于Objective-C运行时。

此外,你可以在你的vc(' s)内扩展Selector并在那里声明你的选择器:

private extension Selector {
    static let updateItems  = #selector(CharactersListVC.updateItems)
    static let getMoreItems = #selector(CharactersListVC.getMoreItems)
}

然后就这样使用它:

button?.addTarget(self, action: .updateItems, forControlEvents: .TouchUpInside)

希望有所帮助:)

答案 1 :(得分:0)

@pkacprzak你是对的,只是对此进行了测试。

选择器(self.handlePan(_ :)正常工作

//这是代码

class Foo:UIView {
override init(frame: CGRect) {
    super.init(frame: frame)
    registerPan()
}
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
func registerPan() {
    let recognizer = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan(_:)))
    //do something with recognizer
    self.addGestureRecognizer(recognizer)
}

@objc func handlePan(recognizer:UIPanGestureRecognizer) {
    //handle pan gesture
    print("From Base")
}
}

class Bar: Foo {
override init(frame: CGRect) {
    super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
override func handlePan(recognizer:UIPanGestureRecognizer) {
    //overriding handle pan gesture
    print("From Child")
}
}

这是如何被称为......

override func viewDidLoad() {
  super.viewDidLoad()
  let bar = Bar(frame: self.view.frame)
  self.view.addSubview(bar)
}