Weak timers

Chapter 6, page 123 has a potential memory leak in it. In this particular program, it’s not possible for this to really leak, but in general it’s worth understanding the correct way to approach it.

In the example code, the view retains an infinitely-repeating NSTimer, for which the view is the target. This is a retain loop, since NSTimer retains its target. There are various ways to fix this, but my favorite is to use a GCD timer with a weak reference to self:

__weak id weakSelf = self;
double delayInSeconds = 0.25;
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
                                dispatch_get_main_queue());
dispatch_source_set_timer(_timer, dispatch_walltime(NULL, 0), 
                          (unsigned)(delayInSeconds * NSEC_PER_SEC), 0);
dispatch_source_set_event_handler(_timer, ^{
  [weakSelf updateValues];
});
dispatch_resume(_timer);

It’s a little verbose, and you often may want to wrap it up in a helper function. But it’s nicely self-contained. The sample code has been updated.

Thanks to Johan Kool (@johankool) for pointing out the original retain loop.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>