安全地释放定时器

时间:2010-09-16 10:17:53

标签: iphone objective-c

我在视图控制器的ViewDidLoad方法中创建了一个计时器。

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(gameLoop:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(gameLoop:)];

NSTimer *t = [NSTimer timerWithTimeInterval: 1./30.
                                 invocation:inv 
repeats:YES];                                   

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];


[[NSNotificationCenter defaultCenter] addObserver:self 
selector:@selector(statTapped:)                                          
name:@"statTapped"
object:nil];

我可以在哪里以及在哪里取消分配?如果我尝试从我的dealloc这样做它不会编译。因为t不是全局的。

-(void) dealloc
{
if (t) 
{
    [t invalidate];
    [t release];
    t=Nil;
}
}

谢谢, 代码

3 个答案:

答案 0 :(得分:2)

最简单的方法是使用属性将其存储在您的实例中:

@property(retain) NSTimer *gameUpdater;

viewDidLoad中:

self.gameUpdater = [NSTimer timerWithTimeInterval:1.0 / 30.0
                                       invocation:inv
                                          repeats:YES];

当您不再需要时,您应该使计时器无效。 (除非它必须继续运行,直到你退出应用程序为止。在这种情况下,没有必要使它失效。)

-dealloc 中执行此操作是个坏主意,因为:

  • Apple可能会在稍后的时间点向cocoa touch添加垃圾收集。如果发生这种情况, dealloc 将不再被调用。除了在 dealloc 中释放对象之外,这也是你不应做任何事情的部分原因。

  • 您的 UIViewController 可能会保留在其他位置,在这种情况下, dealloc 也不会被调用。目前情况可能并非如此,但当您向应用程序添加其他功能时,您可能需要此功能。

使计时器无效的好地方可能是名为“暂停”的按钮或类似操作。

仍然可以在 -dealloc 中完成释放计时器。无效的计时器不再保留其目标。

答案 1 :(得分:1)

使NSTimer成为UIViewController的属性。 在UIViewController的dealloc方法中释放计时器。

@property(nonatomic,retain) NSTimer *t;

答案 2 :(得分:0)

方法 invalidate 将导致计时器从运行循环中删除。根据NACR(New,Alloc,Copy,Retain)的规则,方法 -timerWithTimeInterval 返回一个自动释放对象,因此您无需再次发布。

-(void) dealloc
{
   if (t) 
   {
     [t invalidate];
     //[t release];
     t=Nil;
   }
}