Simple GCD Timer (RNTimer)
I know this exists out there somewhere already, but I couldn’t find it anywhere and I was sick of writing it over and over again…. If someone knows of previous art, please point me in the right direction. I know Fiery Robot’s and Mike Ash’s, but they solve different problems.
Have you ever noticed how hard it is to write a repeating NSTimer that doesn’t create a retain loop? Almost always you wind up with something like this:
[NSTimer scheduledTimerWithTimeInterval:1
target:self
selector:@selector(something)
userInfo:nil
repeats:YES];
Seems easy enough, except it’s a retain loop. Mike Ash does a nice job of explaining it and walking you through the hoops you need to avoid it. For such a common thing, you’d think this would be easy. And it should be, so I fixed it. I just still can’t quite believe I’m the first to do so.
Anyway, for your consideration I present a very simple class called RNTimer. Right now it just handles the most common case: a repeating timer that does not generate a retain loop and automatically invalidates when it is released. It could of course be expanded to handle more NSTimer functionality if there is interest. Let me know if you have a use case that the current implementation doesn’t address.
You may find it along with further information at GitHub.

Hey Rob,
it would be great to implement -fire method to cover cases when you want to fire the repeating timer on demand immediately after it was created on 0 sec. Or maybe it could be an additional argument in method repeatingTimerWithTimeInterval:.
Thanks.
Added. Also added more docs and unit tests.
@Rob Napier Awesome, thanks Rob!
Thanks for this, nice bit of code! I am a bit confused though, it seems to be firing continually instead of every n seconds. Any idea why that could be?
@John Wright weakSelf.timer = [RNTimer repeatingTimerWithTimeInterval:10 block:^{ [weakSelf fetchTickets]; }];
@John Wright Because a uint64_t is much bigger than an unsigned. Wow, that was stupid…. fixed. Added a test case to watch for that.
It just works. <3
I added an issue to suggest a one-time only timer