Objective-C: Using NSTimer

一个使用NSTimer的例子: Create falling objects in your iOS Application using NSTimer

"你使用Objective-C NSTimer类创建计时器对象更简单。一个计时器会等待直到一个特定的时间间隔过去并启动,发送一个指定的消息给目标对象。例如,你可以创建一个NSTimer对象发送消息给窗口,告诉他在一段时间间隔之后更新自己" Apple


两个相关文档:

– Timer Programming Topics for Cocoa 
– Threading Programming Guide


创建一个加入时间表的,不重复的计时器可以像这么做:

[NSTimer scheduledTimerWithTimeInterval:2.0
    target:self
    selector:@selector(targetMethod:)
    userInfo:nil
    repeats:NO];

这将创建一个计时器(是一个指向NSTimer实例的指针),2秒后启动,并调用targetMethod:。

如果你想停止一个重复的计时器(或者在触发之前停止一个不重复的计时器)你需要保持一个被创建好的NSTimer实例的指针;这通常需要一个实例变量,以便你可以在其他的方法里关联他。你可以调用invalidate方法在NSTimer实例上:

[myTimer invalidate];
myTimer = nil;


给实例变量赋值nil是一个很好的做法(例如如果你的设置计时器无效的方法被调用多次,并且实例变量没有设置为nil,NSTimer的实例已被释放,它会抛一个异常)。


还要注意内存管理的方面:

由于runloop保持定时器,从内存管理的角度,通常不需要在scheduled计时器之后保持一个计时器的引用。由于计时器在你指定方法为选择器的时候作为参数传递,你可以在这个方法里合适的时候让计时器无效。在很多情况下,也许甚至在计时器开始之前,你也需要一个让计时器失效的选项。在这种情况下,你需要保持一个计时器的引用,这样你就可以在适当的时候给他发一个失效的消息。如果你创建一个不安排时间表的计时器,那你必须维护一个计时器的强引用,这样才能在用完它之后销毁它。


Scheduled Timer & Using Selector

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];

如果repeats为NO,计时器会在运行选择器之前等待2秒,并在之后停止;

如果repeats为YES,计时器会立即开始并且每2秒重复调用选择器;

要停止计时器你可以调用计时器的invalidate方法:[t invalidate];

作为一个值得注意的方面,代替使用不重复并且在一个特定间隔之后调用选择器的计时器,你可以使用一个像这样的简单表述:

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

这会跟上面的代码有同样的效果,但如果你想每过一段时间调用选择器的话,就需要使用计时器并repeats:YES;



Self-Scheduled Timer

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
                              interval: 1
                              target: self
                              selector:@selector(onTick:)
                              userInfo:nil repeats:YES];

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


这会创建一个计时器会在一个你制定好的时间(例如一分钟之后)启动自己,并每秒都重复自己。


Unscheduled Timer & Using Invocation

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

NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
                      invocation:inv 
                      repeats:YES];

在这之后,你可以在任何你需要的时候像这样手动开启计时器:


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


注意,onTick:方法像这样:

-(void)onTick:(NSTimer *)timer {
   //do something
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章