Liumx31
Liumx31

Reputation: 1210

NSTimer questions (closure, @objc, and etc.)

I'm pretty new to swift and I have some questions about swift and even just basic OOP (so if you can, please be specific with your answers, thanks a lot!)

So I am making an app that has a timer component and the follow code snippets are from that timer class (and the view controller):

  1. I have stop/start function and a deinit:
var timer = NSTimer()
...
func start(){
    self.timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "tick", userInfo: nil, repeats: true)
}
func stop(){
    timer.invalidate()
}
....
deinit(){
    self.timer.invalidate()
}

so my first question is, why do I need to call self.timer in deinit and start but not in stop? Also when does deinit get called and what does it do differently than the stop function (seems to me they both invalidate the NSTimer)?

  1. There is also an initializer:
init (duration: Int, handler: (Int) -> ()){
    self.duration = duration
    self.handler = handler
}

and the initializer is called in the view controller:

private func timerSetUP(hr: Bool, duration: Int){
    timer = Timer(duration: duration){
        (elapsedTime: Int) -> () in
        let timeRemaining = duration - elapsedTime
        println("what is the eT: \(elapsedTime)")
        let timeReStr = self.getHrMinSecLabels(hr, timeremaining: timeRemaining)
    ....}

My question is about the closure, elapsedTime is a property in Timer class and is it just getting passed into the closure in the view controller? Why is there no reference to the Timer class (like timer.elapsedTime)? And I don't really need this closure right? I can just have another function that does the same thing (or is this easier to get the elapsedTime using this closure)?

  1. There is also a Tick function in my Timer class:
@objc func tick(){
    self.elapsedTime++
    self.handler(elapsedTime)
    if self.elapsedTime == self.duration{
        self.stop()
    }
}

This is the selector for self.timer = NSTimer.scheduledTimerWithTimeInterval(), is a selector just a function that gets called every time the timer fires? And do I just need to give NSTimer.scheduledTimerWithTimeInterval() the string name of the selector function? Also why is there @objc, this just looks like a swift function to me?

Upvotes: 1

Views: 308

Answers (1)

Code Different
Code Different

Reputation: 93191

Your questions are loaded. Let me try addressing them one at a time:

why do I need to call self.timer in deinit and start but not in stop

It's personal coding style. self.timer is the same as timer, assuming you don't have a local variable overriding the instance variable.

Also when does deinit get called and what does it do differently than the stop function?

deinit is called when the run time deallocates your object. If you timer is still running at that time, it needs to stop it first. stop just stops the timer but keep the object in memory.

My question is about the closure, elapsedTime is a property in Timer class...

You need to understand closure a bit. elapsedTime is a parameter of the closure/anonymous function. The Timer object passes its elapsedTime property to that anonymous function when the timer fires. Work the same if you rename it like this:

timer = Timer(duration: duration){
    (t : Int) -> () in
    let timeRemaining = duration - t
    println("what is the eT: \(t)")
    let timeReStr = self.getHrMinSecLabels(hr, timeremaining: timeRemaining)
....}

is a selector just a function that gets called every time the timer fires?

Yes. But you need to specify what object to call the function on (see the target parameter in the next question).

And do I just need to give NSTimer.scheduledTimerWithTimeInterval() the string name of the selector function?

Yes, something like this:

// Fire the tellTime() function of the current object every second (1000ms)
self.timer = NSTimer.scheduledTimerWithTimeInterval(
                        timeInterval: 1000,
                        target: self,
                        selector: "tellTime",
                        userInfo: nil,
                        repeats: true)

Also why is there @objc, this just looks like a swift function to me?

This is to make Objective-C code aware of your Swift function. You can skip it if you program exclusively in Swift.

Upvotes: 1

Related Questions