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
}

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