在Swift中使用NSTimer

时间:2014-06-23 15:22:21

标签: swift nstimer

在这种情况下,永远不会调用timerFunc()。我错过了什么?

class AppDelegate: NSObject, NSApplicationDelegate {

    var myTimer: NSTimer? = nil

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

    func applicationDidFinishLaunching(aNotification: NSNotification?) {
        myTimer = NSTimer(timeInterval: 5.0, target: self, selector:"timerFunc", userInfo: nil, repeats: true)
    }
}

9 个答案:

答案 0 :(得分:8)

我对卢克采用了类似的方法。 对于那些“私人方法”纯粹主义者来说,只有一个警告:

不要在Swift中私下进行回调。

如果你写:

private func timerCallBack(timer: NSTimer){

...

你会得到:

timerCallBack:]:发送到实例的无法识别的选择器...由于未捕获的异常'NSInvalidArgumentException'而终止应用程序

答案 1 :(得分:7)

除非您使用NSTimer.scheduledTimerWithTimeInterval

,否则不会自动安排NSTimer
myTimer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "timerFunc", userInfo: nil, repeats: true)

答案 2 :(得分:6)

正如Drewag和Ryan所指出的那样,你需要创建一个预定的计时器(或自己安排)最简单的创建它已经计划好了:

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

您还需要更改timerFunc(和关联的选择器)的定义以获取参数并以'结束:'

func timerFunc(timer:NSTimer!) {
    ...
}

答案 3 :(得分:6)

适用于Swift 3

var timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(ViewController.updateTimer), userInfo: nil, repeats: true);
RunLoop.current.add(timer, forMode: RunLoopMode.commonModes)

答案 4 :(得分:5)

运行循环的Swift 3.0语法:

RunLoop.current.add(myTimer, forMode: .commonModes)

答案 5 :(得分:4)

这是一些代码,演示了如何在没有参数的情况下使用AND调用函数(延迟)。

在xCode(singleViewApplication)的新项目中使用它,并将代码放入标准的viewController中:

class ViewController: UIViewController {

    override func viewDidLoad() {

        super.viewDidLoad()

        NSTimer.scheduledTimerWithTimeInterval(2.0, target: self, selector: Selector("delayedFunctionWithoutParameter:"), userInfo: nil, repeats: false)

        let myParameter = "ParameterStringOrAnyOtherObject"

        NSTimer.scheduledTimerWithTimeInterval(4.0, target: self, selector: Selector("delayedFunctionWithParameter:"), userInfo: myParameter, repeats: false)
    }

    // SIMPLE TIMER - Delayed Function Call
    func delayedFunctionWithoutParameter(timer : NSTimer) {
        print("This is a simple function beeing called without a parameter passed")
        timer.invalidate()
    }

    // ADVANCED TIMER - Delayed Function Call with a Parameter
    func delayedFunctionWithParameter(timer : NSTimer) {

        // check, wether a valid Object did come over
        if let myUserInfo: AnyObject = timer.userInfo {
            // alternatively, assuming it is a String for sure coming over
            // if let myUserInfo: String = timer.userInfo as? String {
            // assuming it is a string comming over
            print("This is an advanced function beeing called with a parameter (in this case: \(myUserInfo)) passed")
        }

        timer.invalidate()
    }
}

请注意,在任何情况下,您都应该使用参数(timer:NSTimer)实现延迟函数,以便能够使计时器无效(终止,结束)。使用passend“timer”,你也可以访问userInfo(在那里你可以放置任何Object,不仅包括String-Objects,还有数组和字典等集合类型)。

原始苹果文档说“” - >计时器将自身作为参数传递,因此该方法将采用以下模式: - (void)timerFireMethod:(NSTimer *)计时器 完全阅读 - > here

答案 6 :(得分:3)

由于这个帖子让我尝试将计时器放在RunLoop上(这解决了我的问题),我也发布了我的具体案例 - 谁知道这可能对某人有所帮助。 我的计时器是在app启动和初始化所有对象期间创建的。我的问题是,虽然它确实安排了计时器,但它仍然没有被解雇。我的猜测是,这是因为scheduledTimerWithTimeInterval在启动App期间将计时器放在不同的RunLoop上。如果我只是初始化计时器然后使用NSRunLoop.mainRunLoop().addTimer(myTimer, forMode:NSDefaultRunLoopMode),它可以正常工作。

答案 7 :(得分:3)

使用swift3,您可以使用

运行它
var timer: Timer?
func startTimer() {

    if timer == nil {
        timer = Timer.scheduledTimer(timeInterval: 3, target: self, selector: #selector(self.loop), userInfo: nil, repeats: true)
    }
}

func stopTimer() {
    if timer != nil {
        timer?.invalidate()
        timer = nil
    }
}

func loop() {
    //do something
}

答案 8 :(得分:2)

要使用OP建议的方法来执行此操作,您需要将其添加到运行循环中:

myTimer = NSTimer(timeInterval: 5.0, target: self, selector:"timerFunc", userInfo: nil, repeats: true)
NSRunLoop.mainRunLoop().addTimer(myTimer, forMode:NSDefaultRunLoopMode)

文档还说目标应该采用参数,但没有它就能正常工作。

func timerFireMethod(timer: NSTimer) { }