NSTimer 用法总结

本文详细介绍了NSTimer的使用方法,包括初始化、触发、停止等操作,并提供了具体的代码示例。此外,还探讨了不同类型的定时器及其适用场景,以及如何利用NSObject方法实现延迟消息发送。


1、初始化

+ (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;

注:不用scheduled方式初始化的,需要手动addTimer:forMode: 将timer添加到一个runloop中。

  而scheduled的初始化方法将以默认mode直接添加到当前的runloop中.


举例:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:10.0 target:self selector:@selector(timerFired:userInfo:nil repeats:NO];

NSTimer *myTimer = [NSTimertimerWithTimeInterval:3.0 target:selfselector:@selector(timerFired:) userInfo:nilrepeats:NO];

[[NSRunLoopcurrentRunLoopaddTimer:myTimerforMode:NSDefaultRunLoopMode];

 

2、触发(启动)

当定时器创建完(不用scheduled的,添加到runloop中后,该定时器将在初始化时指定的timeInterval秒后自动触发。


可以使用-(void)fire;方法来立即触发该定时器;

注:You can use this method to fire a repeating timer without interrupting its regular firing schedule. If the timer is non-repeating, it is automatically invalidated after firing, even if its scheduled fire date has not arrived.

在重复执行的定时器中调用此方法后立即触发该定时器,但不会中断其之前的执行计划;

在不重复执行的定时器中调用此方法,立即触发后,就会使这个定时器失效。

 

3、停止

- (void)invalidate;

这个是唯一一个可以将计时器从runloop中移出的方法。

 

注:

NSTimer可以精确到50-100毫秒.

NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.

Timers的替代方法

如果只是要延迟消息的发送,可以使用NSObject的方法

- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait

+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget


创建Timer的三种方法

1.scheduling a timer with the current run loop 

2.creating a timer that you later register with a run loop

3.initializing a timer with a given fire date

Scheduled Timers

以下两个方法自动注册新创建的timer到当前NSRunLoop对象,NSRunLoop的模式为默认的NSDefaultRunLoopMode

  • + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds invocation:(NSInvocation *)invocation repeats:(BOOL)repeats
  • + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)seconds target:(id)target selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)repeats

只发送一次
[plain]  view plain copy print ?
  1. - (IBAction)startOneOffTimer:sender {  
  2.    
  3.     [NSTimer scheduledTimerWithTimeInterval:2.0  
  4.              target:self  
  5.              selector:@selector(targetMethod:)  
  6.              userInfo:[self userInfo]  
  7.              repeats:NO];  
  8. }  


重复发送消息

注:创建重复发送消息的timer一般需要保存一个引用,因为需要在某个时刻停止发送消息

[plain]  view plain copy print ?
  1. - (IBAction)startRepeatingTimer:sender {  
  2.    
  3.     NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5  
  4.                               target:self selector:@selector(timerFireMethod:)  
  5.                               userInfo:[self userInfo] repeats:YES];  
  6.     self.repeatingTimer = timer;  
  7. }  


Unscheduled Timers

创建未注册的timer,使用时调用addTimer:forMode注册到NSRunLoop对象

[plain]  view plain copy print ?
  1. - (IBAction)createUnregisteredTimer:sender {  
  2.    
  3.     NSMethodSignature *methodSignature = [self methodSignatureForSelector:@selector(invocationMethod:)];  
  4.     NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];  
  5.     [invocation setTarget:self];  
  6.     [invocation setSelector:@selector(invocationMethod:)];  
  7.     NSDate *startDate = [NSDate date];  
  8.     [invocation setArgument:&startDate atIndex:2];  
  9.    
  10.     NSTimer *timer = [NSTimer timerWithTimeInterval:0.5 invocation:invocation repeats:YES];  
  11.     self.unregisteredTimer = timer;  
  12. }  

[plain]  view plain copy print ?
  1. - (IBAction)startUnregisteredTimer:sender {  
  2.     if (unregisteredTimer != nil) {  
  3.         NSRunLoop *runLoop = [NSRunLoop currentRunLoop];  
  4.         [runLoop addTimer:unregisteredTimer forMode:NSDefaultRunLoopMode];  
  5.     }  
  6. }  


Initializing a Timer with a Fire Date

创建一个拥有指定发送日期的timer

[plain]  view plain copy print ?
  1. - (IBAction)startFireDateTimer:sender {  
  2.     NSDate *fireDate = [NSDate dateWithTimeIntervalSinceNow:1.0];  
  3.     NSTimer *timer = [[NSTimer alloc] initWithFireDate:fireDate  
  4.                                       interval:0.5  
  5.                                       target:self  
  6.                                       selector:@selector(countedtargetMethod:)  
  7.                                       userInfo:[self userInfo]  
  8.                                       repeats:YES];  
  9.    
  10.     timerCount = 1;  
  11.     NSRunLoop *runLoop = [NSRunLoop currentRunLoop];  
  12.     [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];  
  13.     [timer release];  
  14. }  

Stopping a Timer

[plain]  view plain copy print ?
  1. - (IBAction)stopRepeatingTimer:sender {  
  2.     [repeatingTimer invalidate];  
  3.     self.repeatingTimer = nil;  
  4. }  
  5.    
[plain]  view plain copy print ?
  1. 也可以从timer发送的消息中停止timer  
[plain]  view plain copy print ?
  1. - (void)countedtargetMethod:(NSTimer*)theTimer {  
  2.    
  3.     NSDate *startDate = [[theTimer userInfo] objectForKey:@"StartDate"];  
  4.     NSLog(@"Timer started on %@; fire count %d", startDate, timerCount);  
  5.    
  6.     timerCount++;  
  7.     if (timerCount > 3) {  
  8.         [theTimer invalidate];  
  9.     }  
  10. }  


Memory Management

1. The run loop maintains the timer that is registered to it.

2. The timer is passed as an argument when you specify its method as a selector

3. You should maintain a strong reference to the unscheduled timer, in order to ensure that it's not deallocated before you use it.

4. A timer maintains a strong reference to its user info dictionary,

5. A timer maintains a strong reference to its target, so you should make sure that your timer's target survive longer than the timer itself.



评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值