博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
08 - NSTimer
阅读量:6487 次
发布时间:2019-06-24

本文共 4637 字,大约阅读时间需要 15 分钟。

Timers 通常是跟NSRunLoop一起使用。但是他们的精确度是有限的,如果你只是想在将来的某个时间点执行某个操作的话,完全可以不用timer而做到这些。

如果你只是想在将来的某个时刻执行某些操作,可以使用下面的方法:

performSelector: withObject:afterDelay:
performSelectorOnMainThread:withObject:waitUntilDone:

上面的这个方法可以达到在某个线程执行操作的目的,通过

cancelPreviousPerformRequestsWithTarget:

方法可以取消或者延迟一个消息以及相关方法的执行。

Timer的使用

当你创建一个timer类实例的时候,必须要配置timer的一些方面,比如当timer实例对象开始工作或者激活的时候应该向哪个对象发送哪个消息。并且需要对timer绑定一个run loop来启动timer,有些创建方法会自动做这些操作,最后如果不想使用的时候需要停止timer。

timer对象的创建

大体来说有三种方法来创建一个timer对象:

  1、在当前run loop 中 Scheduling一个timer

  2、先创建一个timer然后在在一个run loop 中注册

  3、初始化一个在某个确定的时刻激活的timer

在所有的方法中,timer对象都需要明确在timer激活的情况下,需要向什么对象发送什么消息,以及它能否重复。在一些方法中,你还可以设置 user info字典。你可以将你认为在timer对象激活情况下有用的代码添加到这个字典当中。

因为有run loop维持着timer,从对象的生命周期的角度来说,当scheduled(安排)一个timer对象之后并没有必要对其进行引用操作。但是在大多数情况下,你有可能需要在你认为恰当的时候停掉timer的运行,甚至是在timer开始之前,在这种情况下,就需要对timer对象保持引用。这样就可以在任何恰当的时候停掉timer。如果你创建了一个没有进入安排的timer对象的话,应该对对象保持一种强引用,以防止这个timer对象在你再次使用的时候已经被销毁。

timer对象强引用着它的任务,也就是说只要timer对象没有被停掉,它的任务就不会被销毁。

也就是说在任务的dealloc方法中停掉timer并不会起任何作用。

@interface TimerController : NSObject // The repeating timer is a weak property.@property (weak) NSTimer *repeatingTimer;@property (strong) NSTimer *unregisteredTimer;@property NSUInteger timerCount; - (IBAction)startOneOffTimer:sender; - (IBAction)startRepeatingTimer:sender;- (IBAction)stopRepeatingTimer:sender; - (IBAction)createUnregisteredTimer:sender;- (IBAction)startUnregisteredTimer:sender;- (IBAction)stopUnregisteredTimer:sender; - (IBAction)startFireDateTimer:sender; - (void)targetMethod:(NSTimer*)theTimer;- (void)invocationMethod:(NSDate *)date;- (void)countedTimerFireMethod:(NSTimer*)theTimer; - (NSDictionary *)userInfo; @end
1 - (NSDictionary *)userInfo { 2     return @{ @"StartDate" : [NSDate date] }; 3 } 4   5 - (void)targetMethod:(NSTimer*)theTimer { 6     NSDate *startDate = [[theTimer userInfo] objectForKey:@"StartDate"]; 7     NSLog(@"Timer started on %@", startDate); 8 } 9  10 - (void)invocationMethod:(NSDate *)date {11     NSLog(@"Invocation for timer started on %@", date);12 }

Scheduled Timers

下面的这两个类方法将会自动的将timer对象注册到当前的NSRunLoop对象的默认模认式(NSDefaultRunLoopMode)当中当中:

1 scheduledTimerWithTimeInterval:invocation:repeats:2 scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
1 - (IBAction)startOneOffTimer:sender {2  3     [NSTimer scheduledTimerWithTimeInterval:2.04              target:self5              selector:@selector(targetMethod:)6              userInfo:[self userInfo]7              repeats:NO];8 }

两秒钟之后,timer对象被激活,然后就会被移除。

下面的这个方法是创建一个重复执行的timer对象的方法:

1 - (IBAction)startRepeatingTimer:sender { 2   3     // Cancel a preexisting timer. 4     [self.repeatingTimer invalidate]; 5   6     NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:0.5 7                               target:self selector:@selector(targetMethod:) 8                               userInfo:[self userInfo] repeats:YES]; 9     self.repeatingTimer = timer;10 }

 

用一个特定的激活时间来初始化一个timer对象:

可以创建一个timer对象,并且给他一个

initWithFireDate:interval:target:selector:userInfo:repeats:

方法。一旦创建,唯一可以修改的是它的开始时间(使用:setFireDate:)。其他的属性在创建之后就是不可变的了。如果要启用这个timer对象,必须将其添加到一个run loop中去。

下面的这个方法可以展示如何根据一个给定的启用时间来创建一个timer对象,并且通过将其添加到一个run loop中来启用这个timer对象:

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

 

停止一个timer 对象:

可以通过给timer对象发送一个invalidate消息来停止timer对象。也可以给一个不重复的timer对象发送一个invalidate方法在启用之前停掉timer对象。

1 - (IBAction)stopRepeatingTimer:sender {2     [self.repeatingTimer invalidate];3     self.repeatingTimer = nil;4 }5  6 - (IBAction)stopUnregisteredTimer:sender {7     [self.unregisteredTimer invalidate];8     self.unregisteredTimer = nil;9 }
1 - (void)countedTimerFireMethod:(NSTimer*)theTimer { 2   3     NSDate *startDate = [[theTimer userInfo] objectForKey:@"StartDate"]; 4     NSLog(@"Timer started on %@; fire count %d", startDate, self.timerCount); 5   6     self.timerCount++; 7     if (self.timerCount > 3) { 8         [theTimer invalidate]; 9     }10 }

这个方法可以在timer对象启用三次之后停用。因为这个timer是作为一个方法的参数在传递的,三次之后就没有必要将timer对象再作为一个参数了。如果你想更早的停掉timer对象,就需要对timer对象进行引用。

 

转载于:https://www.cnblogs.com/SH9186ios/p/4685143.html

你可能感兴趣的文章
去哪儿搜索引擎QSearch设计与实现
查看>>
POJ 2255 Tree Recovery (二叉树)
查看>>
There are two ways for Datatable download as excel
查看>>
PCA误差
查看>>
烦人的数据不一致问题到底怎么解决?——通过“共识”达成数据一致性
查看>>
抽象类详解
查看>>
《Oracle高性能自动化运维》一一2.2 队列锁(Enqueue Lock)
查看>>
《jQuery Mobile入门经典》—— 2.3 使用JavaScript完成功能
查看>>
让Erlang服务器后台运行
查看>>
APUE笔记七
查看>>
Java二进制指令代码解析
查看>>
我的Python学习记录
查看>>
quzatz --Could not load org.quartz.spi.Trigge...
查看>>
qml实现窗口的拖拽效果
查看>>
Centos安装Mysql
查看>>
android Looper 非UI线程中更新UI
查看>>
js if语句多个条件判断
查看>>
AVPacketList结构体和AVPacketQueue结构体
查看>>
PHP操作redis详细讲解
查看>>
Android学习笔记(一)
查看>>