Do you need help on a specific subject? Use the contact form (Request a blog entry) on the right hand side.

2015-03-12

Using NSTimer in Swift

I use an NSTimer for blinking purposes. As I converted my old code I came across this line:

    // Start the timer if it is not active already.
    if (!blinkTimer)
        blinkTimer = [NSTimer scheduledTimerWithTimeInterval:0.5
                                                      target:self
                                                    selector:@selector(blinkCursorPositionMarker)
                                                    userInfo:nil

                                                     repeats:YES];

My first idea to replace this code was as follows (this seems natural when you use code completion):

        if blinkTimer == nil {
            blinkTimer = NSTimer(timeInterval: 0.5, target: self, selector: "blinkCursorPositionMarker:", userInfo: nil, repeats: true)
        }

But that actually won't work. The timer will not fire. The problem is that the replacement code is not the same as the original code. The Objective-c code uses a factory (class function) to create a timer while the Swift code instantiates a timer itself.
Turns out that when we create a timer ourselves, we also have to assign it to a run loop. Which is not all that difficult, that can be done as follows:

            blinkTimer = NSTimer(timeInterval: 0.5, target: self, selector: "blinkCursorPositionMarker:", userInfo: nil, repeats: true)
            NSRunLoop.mainRunLoop().addTimer(blinkTimer, forMode: NSDefaultRunLoopMode)

But why go through that if the same factory function is available in Swift? The following solution shows the usage of the factory:

        if blinkTimer == nil {
            blinkTimer = NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "blinkCursorPositionMarker:", userInfo: nil, repeats: true)
        }

This code is now the same as the Objective-C code, and the created timer is immediately assigned to the run-loop.

Lesson to self: be careful when replacing a factory function with an object instantiation!

Happy coding...

Did this help?, then please help out a small independent.
If you decide that you want to make a small donation, you can do so by clicking this
link: a cup of coffee ($2) or use the popup on the right hand side for different amounts.
Payments will be processed by PayPal, receiver will be sales at balancingrock dot nl
Bitcoins will be gladly accepted at: 1GacSREBxPy1yskLMc9de2nofNv2SNdwqH

We don't get the world we wish for... we get the world we pay for.

No comments:

Post a Comment