[英]Swift NSTimer unrecognized selector sent to instance timerFireMethod
我在Swift for iOS 9.2中编写了一些计时器代码。我通过xcode下载了最新的iOS 9.2文档
(void)timerFireMethod:(NSTimer *)timer
但这不起作用。 如果我使用这样的签名
func timerFire(timer : NSTimer?)
func timerFire(timer : NSTimer)
然后我得到了错误
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[DSP1.PlayManager timerFire]: unrecognized selector sent to instance
我唯一可以上班的是这样的通话签名
func play(sound : String)
{
bsound = theLM?.getPlayer(sound)
bsound?.delegate = self
bsound?.play()
stimer = NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire"), userInfo: self, repeats: true)
NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}
// Docs say signature should be (void)timerFireMethod:(NSTimer *)timer. Docs are wrong
func timerFire()
{
print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}
但这与通过XCode下载的最新iOS 9.2文档说的应该不相符。
(编辑为更清楚,文档中列出的回调签名无法在运行时工作)
回答:
在对NSTimer的调用中,如果作为Selector传入的函数名称有一个尾随冒号,则表示您希望将计时器作为参数传递给您的方法。 没有冒号意味着您不希望将计时器作为参数传递。
NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire"), userInfo: self, repeats: true)
func timerFire()
要么
NSTimer(timeInterval: 1.0, target: self, selector: Selector("timerFire:"), userInfo: self, repeats: true)
func timerFire(timer : NSTimer)
NSTimer的文档提到了这个选择器参数,但还远未明确。 “选择器应具有以下签名:timerFireMethod :(包括冒号以指示该方法接受参数)。”
你的代码似乎还可以。 计时器的选择器没有预定义的签名,只要你的班级中有一个具有该名称的方法,你就可以随心所欲地使用它。
func play(sound : String) {
// ....
stimer = NSTimer(timeInterval: 1.0, target: self, selector: "methodToRunOnTimerTick", userInfo: self, repeats: true)
NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}
func methodToRunOnTimerTick() {
print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}
还有一件事需要记住,您决定使用的方法也可以在调用时将定时器作为参数接收。 这种情况看起来像这样:
func play(sound : String) {
// ....
stimer = NSTimer(timeInterval: 1.0, target: self, selector: "methodToRunOnTimerTick:", userInfo: self, repeats: true)
NSRunLoop.currentRunLoop().addTimer(stimer!, forMode: NSDefaultRunLoopMode)
}
func methodToRunOnTimerTick(timer: NSTimer) {
print("Player at: \(bsound?.currentTime) out of \(bsound?.duration) seconds");
}
所以你以正确的方式实现计时器,该方法不需要特殊的签名。 如果您需要更多帮助,请告诉我。 祝你的项目好运!
你犯了一个简单而又常见的错误。
您的方法签名应该是:
func timerFire(timer: NSTimer) {}
你的计时器设置应该是:
NSTimer(timeInterval: 1.0, target: self, selector: "timerFire:", userInfo: nil, repeats: true)
错误是您在选择器名称中缺少冒号。 timerFire
与timerFire:
不同timerFire:
。 跳过冒号,它会寻找这样的方法:
func timerFire() {}
没有NSTimer参数。 最好包括参数,然后包括冒号,以便您可以确认您获得的计时器是您期望的计时器。
通知也是如此。 如果您使用的是通知中心,请在方法中包含冒号和通知对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.