08 - NSTimer

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.0
4              target:self
5              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对象进行引用。

时间: 2024-10-08 15:16:17

08 - NSTimer的相关文章

黑马IOS 第2期基础+就业班(完整)

├─01天-ScrollView│  └─视频│          01.UIKit复习&代理介绍.mp4│          02.查看大图&自动布局.mp4│          03.ScrollView常用属性.mp4│          04.喜马拉雅.mp4│          05.放大和缩小.mp4│          06.运行循环简单演示.mp4│          07.倒计时界面布局.mp4│          08.NSTimer简单应用.mp4│         

百度哈斯发卡号是减肥哈卡斯加分了卡斯

http://www.ebay.com/cln/ta_ya20/-/167521224015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398283011/2015.02.08 http://www.ebay.com/cln/ta_ya20/-/167521242015/2015.02.08 http://www.ebay.com/cln/p-m6466/-/167398294011/2015.02.08 http://www.ebay.co

克同极用后管期果要议向中如极示听适VybVfesyhpR

社保划到税务征收,将大大提升社保费的征管效率.税务的征管能力是目前而言最强的,以后税务征收社保不是代收,属于本职了. 之前税局要把社保信息和交个税的工资比对起来有困难!现在好了,个税是自己的,社保也是自己的,比对困难?不存在的! 这一变革,会给那些不给员工上社保.不全额上社保的企业致命一击! 最新案例 前段时间的发改委关于限制特定严重失信人乘坐民航的一则意见--发改财金[2018]385号,其中还有税务总局的联合署名. http://weibo.com/20180408PP/2309279811

iOS容易造成循环引用的三种场景NSTimer以及对应的使用方法(一)

NSTimer A timer provides a way to perform a delayed action or a periodic action. The timer waits until a certain time interval has elapsed and then fires, sending a specified message to a specified object(timer就是一个能在从现在开始的未来的某一个时刻又或者周期性的执行我们指定的方法的对象)

在非主线程里面使用NSTimer创建和取消定时任务

为什么要在非主线程创建NSTimer 将 timer 添加到主线程的Runloop里面本身会增加线程负荷 如果主线程因为某些原因阻塞卡顿了,timer 定时任务触发的时间精度肯定也会受到影响 有些定时任务不是UI相关的,本来就没必要在主线程执行,给主线程增加不必要的负担.当然也可以在定时任务执行时,手动将任务指派到非主线程上,但这也是有额外开销的. NSTimer的重要特性 NSTimer上的定时任务是在创建NSTimer的线程上执行的.NSTimer的销毁和创建必须在同一个线程上操作 NSTi

NSTimer

NSTimer叫做“定时器”,它的作用如下在指定的时间执行指定的任务每隔一段时间执行指定的任务 调用下面的方法就会开启一个定时任务+ (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;每隔ti秒,调用一次aTarget的aSelector方法,yesOr

IOS开发—NSTimer

创建timer对象的三种方法 一.这两个类方法创建一个timer并把它指定到一个默认的runloop模式中 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti invocation:(NSInvocation *)invocation repeats:(BOOL)yesOrNo; + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(i

Bootstrap 3.2.0 源码试读 2014/08/09

第一部分 normalize.css 104至110行 code,    /* 编辑代码 */ kbd,    /* 键盘输入的文本 */ pre, samp {    /* 范例,sample的简写 */   font-family: monospace, monospace;    /* 这个地方应该是写错了,第二字体应该是serif */   font-size: 1em; } 设置字体的大小为1em,字体为monospace. 111至119行 button, input, optgro

笔试算法题(08):输出倒数第K个节点

出题:输入一个单向链表,要求输出链表中倒数第K个节点 分析:利用等差指针,指针A先行K步,然后指针B从链表头与A同步前进,当A到达链表尾时B指向的节点就是倒数第K个节点: 解题: 1 struct Node { 2 int v; 3 Node *next; 4 }; 5 Node* FindLastKth(Node *head, int k) { 6 if(head==NULL) { 7 printf("\nhead is NULL\n"); 8 exit(0); 9 } 10 Nod