2011-04-14 38 views
9
@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并且定时器继续运行。NSTimer禁用UIView中的dealloc

如果我注释掉“timer = [NSTimer schedule ....”部分,dealloc将被调用。这意味着我的代码的所有其他部分正常工作,计时器是罪魁祸首。 runTimer方法是空的,这意味着它只是计时器与我混淆。

回答

14

NSTimer保留目标。因此,在视图解除分配之前,定时器必须失效。

+0

在上海华盈的的dealloc只叫,我把“[someview KillTimer函数]和[someview发布],定时器得到无效,但dealloc中仍然不会被调用 – ssj 2011-04-14 22:42:35

+0

然后其他的东西仍然保留视图 – bbum 2011-04-14 23:03:43

+0

不知道为什么我实施的killtimer方法没有工作我第一次尝试它..但它现在起作用 – ssj 2011-04-15 01:10:36

21

我认为在UIView中使用NSTimer时最好的解决方案是覆盖removeFromSuperview方法;

- (void)removeFromSuperview 
{ 
    [timer invalidate]; 
    timer = nil; 

    [super removeFromSuperview]; 
} 

要记住这里的唯一的事情是,你需要确保timer不是零对象,因为removeFromSuperview还可以获得自动从其他的UIView的超级dealloc的方法调用。你可以包装在一个条件来检查。

+0

removeFromSuperview将发送释放消息的视图。所以我认为我们可以在dealloc中使用它 – SNR 2012-02-10 06:49:39

+0

这对于那些使用ARC的人来说是完美的,谢谢 – BigBadOwl 2012-06-24 17:05:16

0

如上所述,定时器保留其目标。在定时器失效之前,定时器和视图之间有一个保留周期,所以视图不会被释放。

当通过子类didMoveToSuperview从视图层次结构中删除计时器时,计时器将被视为相关更改(例如,超级视图更改)时被系统调用。该“removeFromSuperview”时removeFromSuperview被称为上的UIView

- (void)didMoveToSuperview 
{ 
    [super didMoveToSuperview]; 

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

问题不一定是由保留周期引起的,即使你对定时器有一个弱(或没有)引用, r将被它预定的运行循环保留。 – 2015-02-12 20:19:07