Using an NSTimer in Swift

前端 未结 10 1511
生来不讨喜
生来不讨喜 2020-12-05 06:19

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

class AppDelegate: NSObject, NSApplicationDelegate {

    var myTimer: NSTimer? = nil

             


        
相关标签:
10条回答
  • 2020-12-05 07:01

    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

    0 讨论(0)
  • 2020-12-05 07:09

    With swift3, you can run it with,

    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
    }
    
    0 讨论(0)
  • 2020-12-05 07:14

    Swift 3.0 syntax for the run loop thingy:

    RunLoop.current.add(myTimer, forMode: .commonModes)
    
    0 讨论(0)
  • 2020-12-05 07:14

    Since this thread made me try to put the timer on a RunLoop myself (which solved my problem), I post my specific case as well - who knows maybe it helps somebody. My timer is created during app start up and initialisation of all the objects. My problem was that, while it did schedule the timer, it still never fired. My guess is, this was the case because scheduledTimerWithTimeInterval was putting the timer on a different RunLoop during startup of the App. If I just initialise the timer and then use NSRunLoop.mainRunLoop().addTimer(myTimer, forMode:NSDefaultRunLoopMode) instead, it works fine.

    0 讨论(0)
提交回复
热议问题