2

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)
narner
  • 2,908
  • 3
  • 26
  • 63
user3751185
  • 4,685
  • 3
  • 13
  • 8

1 Answers1

9

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
    }
}
ipmcc
  • 29,581
  • 5
  • 84
  • 147
  • Gave it a try assigning values of timer and queue to my map view. Same result. Any tips as to how to go about this? – user3751185 Jan 28 '15 at 03:44
  • My only guess (from what you've said here) is that your map view is *also* going away at some point. I've added a trivial example where the queue and timer are owned by the AppDelegate and it works as expected. – ipmcc Jan 28 '15 at 11:42