Re: NSTimer memory management
Re: NSTimer memory management
- Subject: Re: NSTimer memory management
- From: Andreas Grosam <email@hidden>
- Date: Fri, 24 Sep 2010 12:06:54 +0200
On Sep 23, 2010, at 3:50 AM, Jeff Johnson wrote:
> Your object retains the timer, and the timer retains your object. That is obviously a kind of retain cycle.
I think, this kind of retain cycle is not a problem by itself when a repeating timer is used.
> What can happen is that your app gets into a situation where the only thing that retains a reference to your object is its own theTimer ivar.
This can not happen that easily when a repeating timer is used, since there must exist one other object holding a reference to the timer and invoking the -invalidate message. The reference to the timer is most likely an ivar of this other object, or the timer is indirectly retained by the other object (say, as an element of NSArray).
> When the timer is invalidated, it releases your object (the target), and at that point it has a 0 retainCount, so your object is immediately deallocated. Then, boom!
I don't think that this can happen in a garbage collected system.
A number of conditions must be true to make a boom happen, though:
- GC is not active (I believe so)
- the run loop is still alive retaining the target, and the timer is still valid
- there is no other object retaining the target!
- there exists a "third object" sending a message (say, -stopTimer) to the target which in turn invokes -invalidate.
- the "third object" does not retain the target!
- the target executes additionally code within this method -stopTimer after sending -invalidate, and thereby accessing ivars.
- the run loop *immediately* releases the timer object itself when the timer is invalidated.
Only then, the target receives -dealloc while it is executing the method -stopTimer -- and then: boom!
@slasktrattenator:
In order to prevent this, it must be ensured, that the *target is retained elsewhere* when the timer will be invalidated. In this case, it is irrelevant whether the target itself retains the timer or not. However, if you do not retain the timer in the target, you must not send it further messages after you sent -invalidate to it. It's a good practice to set the unretained timer reference to nil immediately after invalidating it.
Ensure also that scheduling the timer and invalidating the timer will be invoked in the same thread.
Andreas
_______________________________________________
Cocoa-dev mailing list (email@hidden)
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:
This email sent to email@hidden