NSTimer禁用UIView中的dealloc

问题描述

|
@interface someview:UIView{
  NSTimer* timer;
}
@end

@implementation someview

-(void)dealloc{
  NSLog(@\"dealloc someview\");
  [timer invalidate];
  timer = nil;
}
-(void)runTimer{
//
}
-(void)someMethod{

  timer = [NSTimer timerWithTimeInterval:2.0f target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
}

@end
释放someview不会调用dealloc并且计时器继续运行。 如果我注释掉\“ timer = [NSTimer schedule .... \”部分,则将调用dealloc。这意味着我代码的所有其他部分都正常工作,而计时器是罪魁祸首。 runTimer方法为空,这意味着它只是把我弄乱了。     

解决方法

NSTimer保留目标。因此,在取消分配视图之前,必须使计时器无效。     ,我认为在UIView中使用NSTimer时最好的解决方案是重写removeFromSuperview方法。
- (void)removeFromSuperview
{
    [timer invalidate];
    timer = nil;

    [super removeFromSuperview];
}
这里唯一要记住的是,您需要确保timer不是nil对象,因为removeFromSuperview也可以从其他UIView的super dealloc方法中自动调用。您可以包装一个条件检查。     ,如上所述,计时器保留其目标。在计时器无效之前,计时器与视图之间存在一个保留周期,因此不会取消分配视图。 我将通过将子类ѭ2from从视图层次结构中移除而使计时器无效,当存在与视图相关的更改(例如,超级视图更改)时,系统会调用此计时器。仅在UIView上调用
removeFromSuperview
时才调用\'removeFromSuperview \'
- (void)didMoveToSuperview
{
    [super didMoveToSuperview];

    if (!self.superview)
    {
        [timer invalidate];
        timer = nil;
    }
}