Setup a GCD timer, the print statement "ABTimer Fired" is being called, but not "ABTimer Fired Block" and I cannot figure out why! Any ideas?
Here is my basic code, comment for clairity:
class ABTimer {
private var timer: DispatchSourceTimer!
/// Creates a timer
@discardableResult
init(fire: Date, interval: TimeInterval, repeats: Bool, block: @escaping (ABTimer) -> Void) {
// Cancels existing timers
timer?.cancel()
// Queue a new timer
let queue = DispatchQueue(label: "com.applebot.timer", attributes: .concurrent)
// Make the timer
timer = DispatchSource.makeTimerSource(queue: queue)
// let i = fire.timeIntervalSince(Date()) // Code for determing fire date
if repeats {
// If repeating, schedule a repeating timer
timer?.schedule(deadline: .now(), repeating: interval, leeway: .milliseconds(100))
} else {
// if not repeating, schedule a non-repeating timer
timer!.schedule(deadline: .now())
}
// Set event handler
timer?.setEventHandler(qos: .background) { [weak self] in
print("\(Date()) >>>> NOTICE: ABTIMER FIRED BLOCK")
guard let ss = self else { return }
block(ss)
}
print("\(Date()) >>>> NOTICE: ABTIMER FIRED")
// Start Timer
timer?.resume()
}
}
That isn't enough context. If "t" is a local variable in a function or method, then the ABTimer instance it refers to is going to be released as soon as the current scope ends (or sooner, but really soon either way).
If "t" is a property of a custom type, then it's going to keep the ABTimer instance alive as long as the value of that type exists (and so on outwards).
The fact that it's called "t" (and not something meaningful) suggests it's a local variable.
FWIW, doing this in a playground changes the timing, so the ABTimer instance may be staying alive longer than in an app environment. You can't really conclude anything from that.