我有这样的代码:
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"
答案 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很有意思。