@interface someview:UIView{
NSTimer* timer;
}
@end
@implementation someview
-(void)dealloc{
NSLog(@\"dealloc someview\");
[timer invalidate];
timer = nil;
}
-(
As mentioned above, Timers retain their targets. Until the timer is invalidated, there is a retain cycle between the timer and the view, so the view will not be deallocated.
I would invalidate the timer when it's removed from the view hierarchy by subclassing didMoveToSuperview
, this gets called by the system when there is a View-Related Change (e.g superview changes). The 'removeFromSuperview' is only called when removeFromSuperview
is called on UIView
- (void)didMoveToSuperview
{
[super didMoveToSuperview];
if (!self.superview)
{
[timer invalidate];
timer = nil;
}
}
NSTimer retains the target. Therefore, the timer must be invalidated before your view is dealloc'd.
I think the best solution when using an NSTimer inside of a UIView is to override the removeFromSuperview method;
- (void)removeFromSuperview
{
[timer invalidate];
timer = nil;
[super removeFromSuperview];
}
The only thing to keep in mind here is that you need to ensure that timer is not a nil object because removeFromSuperview can also get automatically called from other UIView's super dealloc methods. You could wrap in a conditional to check.