一個使用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
}