How to create a timer the right way?
I always have an class which needs to set up a timer for as long as the object is alive. Typically an UIView which does some animation.
Now the problem: If I strongly reference the NSTimer I create and invalidate and release the timer in -dealloc, the timer is never invalidated or released because -dealloc is never called, since the run loop maintains a strong 开发者_Go百科reference to the target. So what can I do? If I cant hold a strong ref to the timer object, this is also bad because maybe I need a ref to it to be able to stop it. And a weak ref on a object is not good, because maybe i'm gonna access it when it's gone. So better have a retain on what I want to keep around.
How are you guys solving this? must the superview create the timer? is that better? or should i really just make a weak ref on it and keep in mind that the run loop holds a strong ref on my timer for me, as long as it's not invalidated?
Treat the lifetime of the timer target as being on screen, not between init and dealloc.
For UIView do something like this:
-(void) willMoveToSuperview:(UIView *)newSuperview { [self runMyTimer:newSuperview != nil]; }
For UIViewController do something like this:
-(void) viewWillAppear:(BOOL)inAnimated { [self runMyTimer:YES]; }
-(void) viewDidDisppear:(BOOL)inAnimated { [self runMyTimer:NO]; }
Using something like this:
-(void) runMyTimer:(BOOL)inRun {
if ( inRun ) {
if ( !myTimer ) myTimer = [[NSTimer scheduled...] retain];
} else {
if ( myTimer ) {
[myTimer invalidate];
[myTimer release];
myTimer = nil;
}
}
}
And for completeness you can call [self runMyTimer:NO]
in dealloc.
For timers in View Controllers, my practice is:
scheduledTimerWithTimeInterval in viewDidAppear:
then
invalidate it in viewWillDisapper:
For views, I put relevant timers into viewControllers.
For other things which might go away on their own, I'd use the same strategy. The timer goes into a controller object, which itself refers (weakly) to the object which might go away on its own. The timer then prods the controlled object.
Oftentimes, though, I'm fine with having a strong reference to something. As long as it tells me before it goes away, I can null out my reference -- [nil anyMessage] succeeds ....
精彩评论