On 19/04/2013, at 4:01 PM, Oleg Krupnov <oleg.krup...@gmail.com> wrote:

>  recently encountered an alarming problem that I have never been
> aware of, and I'd like to ask about the best practice to handle it.
> 
> Is it true that any object (let's call it Controller) that owns an
> NSTimer, scheduled to fire a method (let's call it -timerDidFire) of
> the same Controller, creates a circular reference and causes the
> Controller to never be released and the timer never stop triggering?
> 
> It looks like scheduling the timer causes the run loop to retain a
> reference to the object that implements -timerDidFire, in this case
> it's the Controller. Is this true? Then this is a circular reference,
> right?

It depends on whether your controller retains the timer object. There is no 
reason for it to do so, since the run loop retains the timer and the timer 
retains its target (the controller).

There's a still a problem though, in that you need to invalidate the timer in 
order for the controller to be deallocated.

> 
> In this case, if [_timer invalidate]; is called only in Controller's
> dealloc, then the timer never stops firing?

Yup.

> 
> Which is the best way to prevent this problem? Currently I'm thinking
> about some kind of -[controller disconnect]; method that I need to
> call before [controller release]; in controller's parent object, but
> that seems a bit unwieldy solution.


You can always override release to stop the timer but this has the problem that 
whoever performs the first release stops the timer - that may not be who you 
expect. Having a distinct 'disconect' method is certainly a reasonable solution.

There are automatic solutions involving a private proxy object to be the 
timer's target that is owned by the controller. The controller can manage the 
proxy and timer in such a way that the controller can simply be dealloc'd and 
this in turn causes the proxy object to invalidate the timer, then releases the 
proxy. The proxy object is completely internal to your controller so no outside 
code needs to be aware of it.

There might be a better way, but adding an additional level of indirection to 
the timer's target in this way is a solution.

--Graham


_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to