当前位置: 首页 > news >正文

NSTimer的详细用法

NSTimer 详细设置

 
NSTimer 详细设置1:http://blog.csdn.net/davidsph/article/details/7899483
NSTimer 详细设置2:http://blog.csdn.net/davidsph/article/details/7899731
 
1 、、、、、

先说一下我的业务需求,最近在做一个小项目,需要用到定时器的功能,NSTimer类,期间,出现了一些小问题,不过最终通过自己的努力,终于做出来了。我想总结一下,我对NSTimer类的学习和理解。

不多说了,先上效果图

界面元素很简单,两个UIButton 开始和暂停,20表示起始倒计时。最终的效果是,按开始按钮的时候,倒计时开始运行,按暂停按钮的时候,计时器,停止倒计时。当倒计时为0的时候,弹出一个对话框,提示时间已到。

 

业务需求很简单,但是,在我的实现中,却出现了,一些小错误。 主要是暂停键不能点击多次,开始键也不能点击多次,我相信,刚开始,接触这个NSTimer的人,也会出现这几个问题。

 

直接上几个主要的代码:

控制器类的.h文件中

@interface sdsViewController : UIViewController<UIAlertViewDelegate>

//定义一个定时器,做为实例变量
@property(nonatomic,retain) NSTimer *timer;

//显示倒计时当前状态
@property (retain, nonatomic) IBOutlet UILabel *timeDisplay;

//开始按钮,响应的action
- (IBAction)startTime:(id)sender;

//暂停按钮响应的action
- (IBAction)stopTime:(id)sender;

@end



.m中关键代码

开始按钮 响应代码:

- (IBAction)startTime:(id)sender {

 

 //如果定时器对象不存在,则创建一个并启动
    
    if(!_timer){
        
        //创建一个定时器,这个是直接加到当前消息循环中,注意与其他初始化方法的区别
       _timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES]; 


        //  [_timer fire]; //对于这个fire方法,稍后会详解,它不是启动一个定时器,这么简单
        
    }

 

}

//结束按钮响应代码:

 

- (IBAction)stopTime:(id)sender {
    
    if (_timer) {
        NSLog(@"调用 self.time为真!!");


            //如果定时器在运行
        if ([self.timer isValid]) {


            NSLog(@"单击停止按钮,取消定时器!!");
        
            [self.timer invalidate];

        //这行代码很关键
           _timer=nil;
            
        }
        
    }
    
}

一切OK,现在分析程序用到的关键地方。

先看看NSTimer类的结构,比较简单

Tasks

Creating a Timer

//创建一个定时器 ,以下是便利构造器方法,都懂的
+ scheduledTimerWithTimeInterval:invocation:repeats:
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
+ timerWithTimeInterval:invocation:repeats:
+ timerWithTimeInterval:target:selector:userInfo:repeats:

//初始化方法
– initWithFireDate:interval:target:selector:userInfo:repeats:

 

//是开始一个定时器吗,恐怕没那么简单????????
Firing a Timer
– fire

//是暂停一个定时器吗,NO ,是Stop ,写的很清楚

Stopping a Timer
– invalidate

//关于定时器的以下信息
Information About a Timer
– isValid  //是否在运行
– fireDate //Returns the date at which the receiver will fire.
– setFireDate: //重新设置定时器开始运行的时间
– timeInterval  //定时器延时时间
– userInfo //其他信息

------------------------------------------------------
 
2、、、、、、、、、

先说一下,初始化方法

+ scheduledTimerWithTimeInterval:invocation:repeats:
+ scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:

这两个是创建一个定时器,并加入到当前运行循环中,即我们可以这样去理解,这样初始化一个定时器时,在(NSTimeInterval)seconds 时间之后,自动启动定时器。

 

而以下两个初始化方法这不一样:

+ timerWithTimeInterval:invocation:repeats:
+ timerWithTimeInterval:target:selector:userInfo:repeats:

 

这 两个同样是创建,但没有加入到,运行循环中。class method to create the timer object without scheduling it on a run loop.然后,建立之后,必须(after creating it, you must add the timer to a run loop manually by calling the addTimer:forMode: method of the corresponding NSRunLoop object.),这就是与上面两个方法的区别。

  //创建一个定时器
       _timer=[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES];

 

 

 

_timer=[NSTimer timerWithTimeInterval:10 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES];
       //必须手动加入到当前循环中去
       NSRunLoop *runloop=[NSRunLoop currentRunLoop];
       [runloop addTimer:_timer forMode:NSDefaultRunLoopMode];

 

以上两端代码效果是一样的

 

 

关于这个方法:

Firing a Timer
– 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.

这是官方文档的说法,英文说的很清楚,但我们理解还不是很到位,为了彻底搞懂它的功能。我又做了一个测试。

 

也是很简单,把上面那个定时器,改变一点

//初始化的时候创建一个定时器

- (id) initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
    
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    
    if (self) {
        // Custom initialization
        
        //创建一个定时器,
        
       _timer=[NSTimer timerWithTimeInterval:10 target:self selector:@selector(changeTimeAtTimedisplay) userInfo:nil repeats:YES];
      

//手动加入到循环中

      NSRunLoop *runloop=[NSRunLoop currentRunLoop];

 [runloop addTimer:_timer forMode:NSDefaultRunLoopMode];


//当然这个定时器会自动启动,只不多过了十秒之后,才触发

}

return self

}

 

 

当我们单击“开始”按钮时,

 

- (IBAction)startTime:(id)sender {
   
    //只是简单地调用一下这个方法,看到底功能是什么
  [_timer fire];

}

结 果是,单击一下按钮,倒计时减1,单击一下减1,即它把触发的时间给提前了,但过十秒后倒计时还会减1,即它只是提前触发定时器,而不影响之前的那个定时 器设置的时间,就好比我们等不及要去看一场球赛,赶紧把车开快些一样,fire的功能就像让我们快些到球场,但却不影响球赛开始的时间。

还 记得之前那个初始化定时器时,设置的是YES吗,当我们,改为NO时,即不让它循环触发时,我们此时再单击开始按钮。会猛然发现,倒计时减1了,但当我们 再点击开始按钮时,会发现倒计时,不会动了。原因是:我们的定时器,被设置成只触发一次,再fire的时候,触发一次,该定时器,就被自动销毁了,以后再 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.

这就对了,fire并不是启动一个定时器,只是提前触发而已。

转载于:https://www.cnblogs.com/renhuanwei/p/3938966.html

相关文章:

  • Windows下安装Scrapy方法及常见安装问题总结——Scrapy安装教程
  • c# Winform上传文件
  • Codeforces Round #532 (Div. 2)
  • Ubuntu 图形处理软件
  • 【每日笔记】【Go学习笔记】2019-01-10 codis proxy处理流程
  • 创建Windows服务简单流程
  • Airflow成为Apache软件基金会的顶级项目
  • BZOJ 3039: 玉蟾宫
  • JSP学习笔记(一)
  • 《TCP IP 详解卷1:协议》阅读笔记 - 第六章
  • 继承中代码执行顺序
  • 遍历日志文件并打印
  • Spartan6系列之器件引脚功能详述
  • 菠萝大象--sping
  • es6要点
  • HTTP请求重发
  • Intervention/image 图片处理扩展包的安装和使用
  • iOS 颜色设置看我就够了
  • JS变量作用域
  • Kibana配置logstash,报表一体化
  • Linux各目录及每个目录的详细介绍
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • 闭包--闭包之tab栏切换(四)
  • 给第三方使用接口的 URL 签名实现
  • 机器学习中为什么要做归一化normalization
  • 技术发展面试
  • ​MPV,汽车产品里一个特殊品类的进化过程
  • # Swust 12th acm 邀请赛# [ K ] 三角形判定 [题解]
  • #传输# #传输数据判断#
  • $ git push -u origin master 推送到远程库出错
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (day 2)JavaScript学习笔记(基础之变量、常量和注释)
  • (Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (顺序)容器的好伴侣 --- 容器适配器
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (原創) 物件導向與老子思想 (OO)
  • (转) RFS+AutoItLibrary测试web对话框
  • .NET CLR Hosting 简介
  • .NET Core 项目指定SDK版本
  • .net6+aspose.words导出word并转pdf
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .NET使用存储过程实现对数据库的增删改查
  • .net最好用的JSON类Newtonsoft.Json获取多级数据SelectToken
  • .sh
  • :not(:first-child)和:not(:last-child)的用法
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • [ CTF ]【天格】战队WriteUp- 2022年第三届“网鼎杯”网络安全大赛(青龙组)
  • [52PJ] Java面向对象笔记(转自52 1510988116)
  • [ARM]ldr 和 adr 伪指令的区别