Swift选择器到协议功能?

时间:2016-02-17 12:19:26

标签: ios swift swift2

我有这样的代码:

protocol FooP {
   ...
}

extension FooP {
   func doFoo() {
      print("foo")
   }
   func doFoo(timer: NSTimer) {
      doFoo()
   }
}
class A : NSObject, UITableViewDataSource, FooP {
   var timer : NSTimer?

   ...

   func startUpdating() {
      timer = NSTimer.scheduledTimerWithTimeInterval(
         1.0,
         target: self,
         selector: Selector("doFoo:"),
         userInfo: nil, 
         repeats: true
      )
   }
}

不幸的是,当我启动计时程序时程序崩溃

会崩溃
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[xyz.A doFoo:]: unrecognized selector sent to instance 0x7fb2041c4ac0'

我如何使它工作(我想在协议中继续实现doFoo)?

如果我将doFoo移动到A类定义中,一切正常,但正如我所说,我想在协议中实现此功能。

换句话说,我需要选择器说

"Hey I point to function named "doFoo" that is implemented as extension to FooP"

现在选择器似乎在说

"Hey I point to function named "doFoo" that is implemented in A class"

2 个答案:

答案 0 :(得分:1)

尝试在游乐场玩耍。麻烦的是,没有可能在协议扩展中定义@objc func。所以,看看可能的解决方法

public let aConstString: String
public let aConstInteger: Int

如果你在A类中移动doFoo,为什么它适合你呢?那是因为你的类继承自NSObject,所以不需要@objc关键字。

答案 1 :(得分:1)

问题是,NSTimer和整个Selector()业务都是Objective-C的东西,并且由于桥接而在Swift域中工作。但是,Swift的默认协议实现桥接到Objective-C仙境(还),这就是你的计时器失败的原因。基本上,从Objective-C角度来看,类型为A的对象会响应选择器doFoo:,句点。

因此,将这个用例报告给swift-evolution以获得长期解决方案。短期,使用某种解决方法。

顺便说一下,你可能会觉得阅读(甚至参与)thread很有意思。