SwiftyTimer
SwiftyTimer copied to clipboard
Crash when calling fire() after creating timer
The following code worked with 1.3.0 but crashes with 1.4.0:
let timer = NSTimer.every(1) {
print("do something!")
}
timer.fire()
The internal refactoring of not using NSTimer initializers might be the problem.
could you give more info? OS version, crash log?
Crashed: com.apple.main-thread EXC_BAD_ACCESS KERN_INVALID_ADDRESS 0x0000000043000002
Crashed: com.apple.main-thread 0 libobjc.A.dylib 0x19860dbc8 objc_msgSend + 8 1 CoreFoundation 0x1839f3580 -[__NSCFTimer fire] + 120
This is happening on every device, every OS I tried (iOS, iPhone)
Looks like the CFTimer → NSTimer bridging is lacking, and a bridged timer doesn't actually have a fire()
method...

It is an edge case, but still worth reverting to the old method of initializing timers...
@BenchR267 Would you mind filing the bug with Apple (bugreport.apple.com), so that it's also fixed for everyone?
Oh yeah, sorry, forgot to answer. I'll create a bugticket at Apple.
@radex Will you revert to the old way anytime soon? Asking because you said you would, but there have been no changes to that.
I intend to… The trouble is that if I do that, I lose compatibility with SwiftPM (old method requires ObjC runtime)... Perhaps a conditional implementation (Using either CFRunLoopTimer
API or the new block-based API) would do the job. PRs welcome.
Is there a workaround for this? Its crashing my app as well.
@scisci we are using an older version of SwiftyTimer which doesn't have the issues.
I also encountered this issue, The context is if the user is about to switch views that if a certain timer that calls a function to hide certain messages has not done so when its about to switch, it fires then invalidates the timer.
So instead of fire()
i set the fireDate
to now and then have a completion block for any code that needs to happen after the timer has fired (e.g invalidating after firing). If the code after the call is not dependant on the timer firing it does not need to be in the block.
typealias VanillaClosure = () -> Void
@objc(fireNowThen:)
func fire(completionBlock: VanillaClosure?) {
fireDate = Date()
MTq.after(0.1) {
completionBlock?()
}
}
MTq is a legacy obj-c library, which is just syntax sugar for GCD that could easily be GCD or any other GCD-esque library
This just got me as well, a bummer! Luckily in this project I targeted iOS 10, which does have a Timer API that is closer to SwiftyTimer in simplicity and elegance.