import Foundation
class IncrementingCounter {
private class TimerTargetWrapper {
weak var target: IncrementingCounter?
init(target: IncrementingCounter?) {
self.target = target
}
@objc func tick(timer: Timer) {
target?.incrementCounter()
}
}
private var counter = 1
private var timer: Timer?
deinit {
print(“Counter deinited”)
timer?.invalidate()
}
func start() {
print(“Starting timer”)
guard timer == nil else { return }
timer = Timer.scheduledTimer(timeInterval: 1,
target: TimerTargetWrapper(target: self),
selector: #selector(TimerTargetWrapper.tick(timer:)),
userInfo: nil,
repeats: true)
print(“Scheduled timer”)
}
@objc private func incrementCounter() {
print(counter)
counter += 1
}
}
var counter: IncrementingCounter? = IncrementingCounter()
counter?.start()
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(5)) { [weak counter] in
print(“Setting counter to nil”)
counter = nil
}
CFRunLoopRun()
]]>Best regards,
swifting.io
You might also consider not having your interactor dependent on a concrete class like NSTimer, but rather an abstract role like an Updater. By using a test updater (that you control) in your tests you can ensure the interactor responds properly when it is told to update its content. This means your test can execute in milliseconds, rather than 15 seconds.
How/when an update is triggered is outside the responsibility of the interactor. In your production code, you could have a TimedUpdater that uses NSTimer to determine when to trigger an update.
]]>