Using an NSTimer in Swift

2019-01-13 20:00发布

In this scenario, timerFunc() is never called. What am I missing?

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)
    }
}

标签: swift nstimer
10条回答
forever°为你锁心
2楼-- · 2019-01-13 20:39

Swift 3.0 syntax for the run loop thingy:

RunLoop.current.add(myTimer, forMode: .commonModes)
查看更多
该账号已被封号
3楼-- · 2019-01-13 20:42

i use a similar approach to Luke. Only a caveat for people who are "private methods" purists:

DO NOT make callback private in Swift.

If You write:

private func timerCallBack(timer: NSTimer){

..

you will get:

timerCallBack:]: unrecognized selector sent to instance... Terminating app due to uncaught exception 'NSInvalidArgumentException'

查看更多
【Aperson】
4楼-- · 2019-01-13 20:42

This is a bit of code, that demonstrates how to call a function (delayed) with AND without a parameter.

Use this in a new project in xCode (singleViewApplication) and put the code into the standard 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()
    }
}

Notice, that in any case you should implement the delayed function with the parameter (timer : NSTimer) to be able to invalidate (terminate, end) the timer. And with the passend "timer" you have also access to the userInfo (and there you can put any Object, not only String-Objects, as well collection types such as arrays and dictionaries).

Original Apples documentations says "" -> The timer passes itself as the argument, thus the method would adopt the following pattern: - (void)timerFireMethod:(NSTimer *)timer Read fully -> here

查看更多
爷、活的狠高调
5楼-- · 2019-01-13 20:47

For 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)
查看更多
登录 后发表回答