【问题标题】:Having trouble with NSTimer (Swift)NSTimer (Swift) 遇到问题
【发布时间】:2014-11-08 10:20:43
【问题描述】:

--编辑更新信息--

我想做的是使用NSTimer.scheduledTimerWithTimeInterval 方法每五秒调用一次名为timerFunc 的函数,问题似乎是在运行时,我得到了错误

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-      
[Animation.ViewController timerFunc:]: unrecognized selector sent to instance 0x7fe548d66040'

在输出日志中。我一直在查找其他人的 NSTimers 无济于事,我看到很多选择器都使用 selector: Selector("timerFunc:") 而不是 selector: Selector("timerFunc") 两种方式,但是,给出错误。另一件事是 timerFunc 函数和 NSTimer 都在 viewDidLoad 中,这有什么问题吗?非常感谢您对问题的任何见解,感谢阅读。

下面的timerFunc

func timerFunc(){

    println("Timer")
}

NSTimer 下面

NSTimer.scheduledTimerWithTimeInterval(
        5.0,
        target: self,
        selector: Selector("timerFunc"),
        userInfo: nil,
        repeats: true)

【问题讨论】:

  • 你的 timerFunc 的签名是什么?
  • @vacawama 签名?目前我正试图让 NSTimer 工作,所以我的 timerFunc 只是一个println("Timer") 我将我的 timerFunc 添加到主要问题中。我已经弄清楚了我之前的问题,只是我不需要调用 timeInterval:,它出于某种原因搞砸了。当前的问题是它在编辑器中没有给我一个错误,但是当我运行它时,输出日志在几行乱码中显示Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Animation.ViewController timerFunc]: unrecognized selector sent to instance 0x7fcc53e67010
  • 我只是确保您的timerFunc 没有带参数。你的没有,所以这不是问题。你的timerFuncViewController 的方法吗?
  • @vacawama 我的 timerFunc 是 viewDidLoad 内部的一个函数,它位于 ViewController 内部。我通过在我的 NSTimer 位置旁边写一个timerFunc() 来测试它是否可以被我的 NSTimer 调用,证明它可以访问我的 NSTimer 所在的位置。然而,也许我的 NSTimer 在我的 viewDidLoad 中没有访问权限?我应该为它创建一个带有特殊子类的全新类吗?如果有,是什么子类?
  • 在下面查看我的答案。

标签: swift nstimer


【解决方案1】:

Swift 方法的第一个参数不包含标签。所有其他人通常都会这样做。您应该期望语法是:

NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "timerFunc", userInfo: nil, repeats: true)

【讨论】:

  • 是的,我更仔细地研究了其他人的代码并得出了这个结论,但是,现在每当我运行它时,输出日志都会给我错误Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[Animation.ViewController timerFunc]: unrecognized selector sent to instance 0x7fcc53e67010我将如何捕获这个异常>?
  • 我刚刚澄清了它是通过注释掉我的 NSTimer 并使用 timerFunc() 行调用 timerFunc 来实现的。似乎它只是没有将 timerFunc 识别为选择器,尽管我不知道为什么。
  • 我只是想,我的 NSTimer 放在哪里重要吗?现在它在 viewDidLoad..
【解决方案2】:

在 Swift 中使用选择器时,您需要在函数名称周围使用 Selector() 伪函数:

NSTimer.scheduledTimerWithTimeInterval(5.0,   target: self, 
                                            selector: Selector("timerFunc"), 
                                            userInfo: nil,
                                             repeats: true);

我怀疑出现看似令人困惑的错误的原因是由于选择器名称的类型错误(字符串而不是选择器),编译器无法将您的参数列表与特定方法匹配。

这也解释了这样一个事实,即当您确实设法让它编译时(如 cmets 中提到的另一个答案)它在运行时失败。编译时的类型检查未能发现此类错误(因此运行时异常报告“无法识别的选择器”)。

【讨论】:

  • 一般来说您不需要这样做,因为它会自动为您处理。
  • 遗憾的是,我遇到了完全相同的运行时错误。它可能会自动将其转换为 Selector 类型,我尝试将其更改为 selector: Selector("timerFunc"), 无济于事。我当前的代码已添加到问题中。
  • 我只是想,我的 NSTimer 放在哪里重要吗?现在它在 viewDidLoad..
【解决方案3】:

另外,timerFunc 函数和 NSTimer 都在 viewDidLoad 中,这有什么问题吗?

是的。那是你的问题。 timerFunc 不能嵌套在 viewDidLoad 内部,它必须是与 viewDidLoad 同级的顶级函数。

class ViewController: UIViewController {

    override func viewDidLoad() {
        ....
        NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "timerFunc", userInfo: nil, repeats: true)
    }

    func timerFunc() {
        println("Timer")
    }

}

当定时器触发时,它会在target指定的对象上调用选择器指定的函数。也就是说,它将调用self.timerFunc()。当您的timerFunc() 嵌套在ViewDidLoad 中时,它找不到它。

【讨论】:

  • 至于为什么:使用选择器动态调用的方法必须是老派的objc方法。默认情况下,继承自 NSObject 的类的所有方法,但如果您不扩展 NSObject,则可以使用@objc 标记它们。
【解决方案4】:

计时器不适用于私有方法回调。另外,确保你的类继承自 NSObject。纯 Swift 类将不起作用。

更多信息可以在这里找到:https://github.com/NxSoftware/NxSwiftTimer

【讨论】:

  • 是的,那是我的问题,类需要继承自NSObject
  • +500 用于 NSObject 的东西!
  • 我似乎对私有类的公共函数有同样的问题,如果我将私有类设置为内部,它工作得很好,知道为什么@Antoine?
  • 这些信息不足以让我给出一个好的答案。我建议用一些代码示例打开一个新线程。
【解决方案5】:

我的问题是选择器指向一个私有函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-07
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    相关资源
    最近更新 更多