繁体   English   中英

Swift NSTimer无法识别的选择器发送到实例timerFireMethod

[英]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文档说的应该不相符。

  • 我这样做了吗?
  • 为什么新加载的iOS 9.2文档似乎有错误的签名?
  • 有什么其他人阅读Swift iOS编程的准确文档?

(编辑为更清楚,文档中列出的回调签名无法在运行时工作)

回答:

在对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)

错误是您在选择器名称中缺少冒号。 timerFiretimerFire:不同timerFire: 跳过冒号,它会寻找这样的方法:

func timerFire() {}

没有NSTimer参数。 最好包括参数,然后包括冒号,以便您可以确认您获得的计时器是您期望的计时器。

通知也是如此。 如果您使用的是通知中心,请在方法中包含冒号和通知对象。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM