NSTimer应用
NSTimer应用
在参与项目开发中遇到了NSTimer的应用,虽然我负责的模块内只用到了一小部分,但我觉得还是有必要拿出来好好琢磨一下。
一、概念(来自官方描述)
官网上最新的定义是“A timer that fires after a certain time interval has elapsed, sending a specified message to a target object.” 也就是经过一定时间间隔后触发,向目标对象发送指定消息的计时器。
1、概述
定时器和run loops协同工作。而且run loops保持对定时器的强引用,所以不需要维护添加到run loops后的定时器。同时为了高效使用计时器,必了解run loops如何运行的。
计时器不是一个实时生效的机制。如果定时器启动时刻正一个很长时间的callout或者run loop处于一个不再检测这个定时的模式,它将不启动直到run loop检测到下一个启动时刻。所以定时器真正开始生效的时间是在程序设定启动之后的一段时间内。
NSTimer 是“tool-free bridge”模式,在Core Foundation中对应着CFRunLoopTimerRef。(几个专业名词对我来说真的有些陌生,小菜鸡真的还有很多要学习……)
2、重复和非重复定时器
在初始化定时器时,你需要明确这个定时器是否重复。 一个非重复的定时器触发一次后自动失效,从而阻止了定时器的再次触发。相反的是一个重复的定时器触发结束后重新把自己放到run loops中,准备下一次启动。重复计时器总是根据预定的触发时间来调度自己,而不是实际的触发时间。例如,如果一个定时器预定在某个特定的时间触发,每5秒之后,预定的触发时间将永远落在原来的5秒时间间隔内,哪怕是实际发射时间被推迟了。如果触发时间被延迟到通过一个或多个预定的触发间隔,则定时器仅在该时间内发射一次;然后触发后定时器被重新调度,为了未来预定下一次触发。
3、定时器的容差
在iOS 7 以及之后的版本和macOS 10.9以及之后的版本,你能指定定时器的容差。在定时器触发时,这个灵活性提高了系统的优化能力,以提高功耗和响应能力。定时器可能在任何预定的触发时间和预定加上容差的时间内触发,不会在预定的触发时间前触发。对于重复定时器,下一个触发时间是从初始的触发时间计算出来的,不管在单个触发时间内的容差,以免漂移。默认值是0,则意味着不使用额外的的容差。系统保留对部分定时器应用少量容差的权利,而不管容差的特性。
作为定时器的使用者,你能决定定时器的适当容差。一条普遍的规则,将对至少10%的区间的容差设置为重复定时器。即使是少量的容错也会对应用程序的效率产生显著的积极影响。系统能强制执行容差的最大值。
4、在Run Loops里安置定时器
你能在一个唯一的run loops中注册一个定时器,尽管它可以被添加到run loops中的多个run loops模式中。这有三种新建定时器的方法:
·用方法 scheduledTimerWithTimeInterval:invocation:repeats: 或者
scheduledTimerWithTimeInterval:target:selector:userInfo:repeats: 类方法来创建定时器,并在默认模式下被安置到当前的run loop上。
·用方法timerWithTimeInterval:invocation:repeats:
或者 timerWithTimeInterval:target:selector:userInfo:repeats:类方法来创建定时器对象,且无需在run loops上调度它。(创建后,必须手动安置到一个run loop里,通过调用NSRunLoop的函数
addTimer:forMode:
)
·开辟资源并初始化定时器用 initWithFireDate:interval:target:selector:userInfo:repeats:方法。(同样,你必须手动安置到一个run loop里通过调用NSRunLoop的函数
addTimer:forMode:
)
一旦在run loops上调度,定时器就在指定的的间隔中触发,直到它失效为止。非重复的定时器在触发结束后立刻无效。但对于重复定时器,必须通过调用它的无效方法来使定时器对象无效。调用这个方法要求从当前的run loops中删除定时器,因此你应该在安装定时器的同一线程中调用无效方法。无效的定时器立即禁用为了不让它再影响run loop。之后run loop将删除定时器(以及对应的强引用),或者在还原方法返回前或稍后的某个时间点。一旦失效,定时器对象将不能被重用。
在重复定时器触发后,它将调度最近间隔的的下一个触发,即在最后一次预定的触发时间内,在指定的容差范围内,定时器间隔的整倍数。如果调用执行选择器或者调用时间长于指定的间隔,则定时器只安排下一次触发。那是定时器为不试图弥补错过触发在调用指定的选择器或调用发生。
5、子类注意事项
不要尝试用NSTimer生成子类。
二、实例操作
我应用到NSTimer的开发部分是为了实现发送验证码状态转换的按钮,实现效果如右动图
首先要在设置“发送验证码”按钮时做好接口
[self.sendVerificationCode addTarget:self action:@selector(pressGainCode:) forControlEvents:UIControlEventTouchUpInside];
配置相关的方法(实例中我取名为pressGainCode),为了支持重复获取验证码的情况,我使用的是重复定时器。
- (void)pressGainCode:(UIButton *)btn {
[self validationCodeTimer];
} - (void)validationCodeTimer{
__block int timeout = ; //倒计时时间
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, );
_timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, , ,queue);
dispatch_source_set_timer(_timer,dispatch_walltime(NULL, ),1.0*NSEC_PER_SEC, ); //每秒执行
dispatch_source_set_event_handler(_timer, ^{
if(timeout <= ){ //倒计时结束,关闭
dispatch_source_cancel(_timer);
dispatch_async(dispatch_get_main_queue(), ^{
self.sendVerificationCode.userInteractionEnabled = YES;
self.sendVerificationCode.enabled = YES;
[self.sendVerificationCode setTitle:@"重获验证码" forState:UIControlStateNormal];
});
}
else {
timeout--;
NSString *strTime = [NSString stringWithFormat:@"%d秒后重发",timeout];
dispatch_async(dispatch_get_main_queue(), ^{
self.sendVerificationCode.enabled = NO;
[self.sendVerificationCode setTitle:strTime forState:UIControlStateDisabled];
});
}
});
dispatch_resume(_timer);
}
参考资料:Apple官方文档 、四个实用demo 、定时器总结 、官文翻译及基础操作
NSTimer应用的更多相关文章
- Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用
OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...
- 解决NSTimer存在的内存泄漏的问题
创建定时器会在一定的间隔后执行某些操作,一般大家会这样创建定时器,这样创建的定时,self对定时器有个引用,定时器对self也有个引用,造成了循环引用,最终造成了内存泄漏,如果定时器在做下载的操作就会 ...
- NSTimer
NSTimer叫做“定时器”,它的作用如下 在指定的时间执行指定的任务 每隔一段时间执行指定的任务 调用下面的方法就会开启一个定时任务 + (NSTimer *)scheduledTimerWithT ...
- NSTimer整理总结
对于定时器NSTimer,我们大家都不会陌生,在使用的时候,我们常常会遇到一些坑,例如:在Scrollview拖动时,timer会暂停:在子线程中如何创建一个定时器等.针对于一些我们所遇到的坑,我来总 ...
- ios - NSTimer中target的self是强引用问题
当控制器ViewController跳转进入控制器OneViewController中的时候开启定时器,让定时器每隔一段时间打印一次,当OneViewController dismiss的时候,控制器 ...
- ios基础篇(二十三)—— 定时器NSTimer与图片的自动切换
一.NSTimer NSTimer是一个能在从现在开始到后面的某一个时刻或者周期性的执行我们指定的方法的对象.可以按照一定的时间间隔,将制定的信息发送给目标对象.并更新某个对象的行为.你可以选择在未来 ...
- NSTimer “定时器”
•NSTimer叫做“定时器”,它的作用如下 Ø在指定的时间执行指定的任务 Ø每隔一段时间执行指定的任务 Ø •调用下面的方法就会开启一个定时任务 + (NSTimer *)scheduledTime ...
- IOS OC 多任务定时器 NSRunLoop 管理 NSTimer
下面有两种做法 1.使用日期组件 NSDateComponents 2.使用NSString 生成一个日期 // 创建一个日历对象 NSCalendar *calendar = [NSCalenda ...
- iOS NSTimer使用详解 开启、关闭、移除
定时器定时器详解ios定时器关闭定时器NSTimer 一,要使用一个定时器首先要定义一个定时器: @property (strong, nonatomic) NSTimer *myTimer;//定时 ...
- NSTimer的使用[zhuang]
NSTimer 的头文件 /* NSTimer.h Copyright (c) 1994-2015, Apple Inc. All rights reserved. */ #import <Fo ...
随机推荐
- TCP三次握手的思考?
大家都知道TCP有三次握手的过程,今天我就仔细想了想为什么TCP要有三次握手 先贴一张三次握手的示意图,说明一点是在三次握手中A是在第二次握手后申请缓存资源,B是在第一次握手后申请. 其实这个问题就是 ...
- 微信内嵌浏览器打开手机浏览器下载APP(APK)的方法
想必大家会经常碰到网页链接在微信内无法打开和微信内无法打开app下载页的情况.通常这种情况微信会给个提示 “已停止访问该网址” ,那么导致这个情况的因素有哪些呢,主要有以下四点 1.网页链接被举报次数 ...
- css 三角
http://peunzhang.github.io/demo/css_angle/index.html
- 【推荐】HTML5 Word Cloud——中文词云
在线工具: http://timdream.org/wordcloud/# 源码: https://github.com/timdream/wordcloud
- Dynamic learning rate in training - 培训中的动态学习率
I'm using keras 2.1.* and want to change the learning rate during training. I know about the schedul ...
- js截取固定长度字符串,多余字符显示...
function cutstr(str, len) { var str_length = 0; var str_len = 0; str_cut = new String(); str_len = s ...
- 文件操作fopen
这块所谓的"文件操作"就是把文件的内容读进程序,然后根据具体的格式进行解析,或者是显示,或者是修改. 也就是把一个文件加载到程序里面,然后对其进行修改. 文件操作就三步(固定的三步 ...
- egret 简单的一笔画算法,在wing中可以直接跑(以后玩这类游戏就有个作弊器了)
/** * 在Main中创建游戏场景 * Create a game scene */ private createGameScene() { MtwGame.Instance.init(this.s ...
- 怎么获取红米6 Pro的root权限
红米6 Pro能有啥方法获得ROOT超级权限?做开发的人知道,android设备有ROOT超级权限,如果手机获得root相关权限,就能够实现更强大的功能,举例子,做开发的人部门的营销部门的妹子,使用一 ...
- RAID配置多阵列
感谢: https://www.cnblogs.com/hystj/articles/8672029.html