user3751185
user3751185

Reputation: 4755

Timer Not Repeating (Grand Central Dispatch)

I'm trying to learn how to dispatch computations on a background thread and resultantly update the UI after. When I attempt this in an existing project with Google Maps, "background" followed by "main" is printed once. No more printing occurs, as if the timer does not repeat.

Further, when I create a blank application and add this code in, nothing prints at all.

let queue = dispatch_queue_create("myTimer", nil);
let timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);

dispatch_source_set_event_handler(timer) {
    println("background")
    dispatch_async(dispatch_get_main_queue(), { println("main") })
}

dispatch_resume(timer)

Upvotes: 2

Views: 3148

Answers (1)

ipmcc
ipmcc

Reputation: 29946

Make sure that something long-lived has a reference to both this queue and this timer. Without explicitly checking, my impression from your snippet here is that timer and queue will be released when this goes out of scope. The dispatch_resume may cause the first event to be queued up, which may cause queue and timer to live long enough to perform the first iteration, after which their retain counts go to zero and they get deallocated.

Try making sure they stick around for a while...

For instance, starting from the iOS Single View Application project template in Xcode, and with the following in AppDelegate.swift, the timer repeats just fine:

import UIKit

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?
    var queue: dispatch_queue_t?
    var timer: dispatch_source_t?

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        queue = dispatch_queue_create("myTimer", nil);
        timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);

        dispatch_source_set_event_handler(timer) {
            println("background")
            dispatch_async(dispatch_get_main_queue(), { println("main") })
        }

        dispatch_resume(timer)

        return true
    }
}

Upvotes: 9

Related Questions