Search code examples
iosswiftreactive-cocoareactive-swift

QueueScheduler not firing when interval is set


This code doesn't print anything:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
 QueueScheduler.main.schedule(after: Date() + 1.seconds, 
                              interval: .seconds(1)){
                                print("test Output")}
 return true
}

but if I do it without interval: it prints one time as expected. Why so?


Solution

  • The variation without interval is using DispatchQueue.main.asyncAfter and checking for disposal before executing the action. So the action will run unless you explicitly call dispose on the returned Disposable.

    But the variation with interval is using DispatchSource.makeTimerSource and then capturing the returned DispatchSourceTimer in the resulting AnyDisposable action. Since DispatchSourceTimer cancels itself when it is released, you must store the returned Disposable or else it deinits and the timer is cancelled.

    I don't know if this is intentional behavior or a bug. On the one hand it's a bit confusing that such similarly named methods act differently in this regard. But on the other hand, the one that repeats on an interval is much easier to leak if you forget to handle the Disposable it returns, so perhaps it makes sense.

    Update:

    This is a bug and is fixed in 3.1.0.