问题

应用需要调度代码以在特定的时间执行。此外,你还想要重复执行任务。

解决方案

使用NSTimer调度代码以在特定的时间执行。为了使用NSTimer,你需要有日期对象与指向应用的运行循环的引用。

注意:

NSTimer需要有运行循环,如果想在Mac或iOS应用中使用定时器,就必须有运行循环。本攻略需要应用带有运行循环。1.11与1.12节分别介绍了创建Mac与iOS应用的步骤。

说明

本攻略的代码位于应用委托中。通常情况下,定时器会放在自定义类或是应用控制器中。

定时器会从特定的日期与时间开始向对象发送消息。如果应用需要重复,那么定时器可能会间隔一段时间后再发送消息。你首先需要有日期对象,用来表示定时器开始向对象发送消息的日期与时间:
NSDate *scheduledTime = [NSDate dateWithTimeIntervalSinceNow:10.0];

上述调度时间位于上面这一行代码执行后的10秒钟。可以在这里使用任何日期。

接下来,通过initWithFireDate:interval:target:selector:userInfo:repeats:构造函数创建定时器:
SString *customUserObject = @"To demo userInfo";

NSTimer *timer = [[NSTimer alloc] initWithFireDate:scheduledTime
                                          interval:2
                                            target:self
                                          selector:@selector(task)
                                          userInfo:customUserObject
                                           repeats:YES];

这里有些内容需要说明一下。第1个参数是日期对象,指定了定时器何时变成活动状态。接下来是间隔时间,是定时器再次发送消息前所需等待的秒数。之后是目标参数描述符,目标是方法所处的对象。selector参数是位于圆括号中的方法名,前面是@selector关键字。由于方法与定时器一样都位于应用委托中,因此可以使用self关键字。

userInfo是定时器使用的自定义内容。可以使用任何对象,并且可以获得正在执行的消息中的对象引用(上面的selector参数)。这里使用了字符串,但通常会使用字典或其他集合以支持更加复杂的活动。

repeats参数表示定时器是发送一次消息,还是根据第2个参数指定的时间间隔重复发送。

接下来需要指向运行循环的引用。可以通过NSRunLoop的currentRunLoop函数获得该引用:
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

现在,只需要将定时器添加到运行循环中即可:
[runLoop addTimer:timer forMode:NSDefaultRunLoopMode];

10秒钟后,定时器将会开始每隔两秒钟向应用发送task消息。

启动之后,如果想停止定时器,可以向定时器发送invalidate消息。这会从运行循环中删除定时器,代码如下所示:
[timer invalidate];

参见程序清单5-7。

代码

程序清单5-7 main.m
#import "AppDelegate.h"

@implementation AppDelegate
@synthesize window = _window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification{
    NSDate *scheduledTime = [NSDate dateWithTimeIntervalSinceNow:10.0];
    NSString *customUserObject = @"To demo userInfo";
    NSTimer *timer = [[NSTimer alloc] initWithFireDate:scheduledTime
                                              interval:2
                                                target:self
                                              selector:@selector(task)
                                              userInfo:customUserObject
                                               repeats:YES];
    NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addTimer:timer forMode:NSDefaultRunLoopMode];
}

-(void)task:(id)sender{
    NSTimer *localTimer = (NSTimer *)sender;
    NSLog(@"Schedule task has executed with this user info: %@", [localTimer  userInfo]);
}

@end

使用

要想使用上述代码,请从Xcode构建并运行Mac应用。注意控制台窗口以及消息何时开始打印到日志中。此处打印出了时间戳,这样就可以看到时间间隔的运作方式了:
2012-01-19 15:23:28.651 Timer[31067:707] Schedule task has executed with  this user info: To demo userInfo
2012-01-19 15:23:30.651 Timer[31067:707] Schedule task has executed with  this user info: To demo userInfo
2012-01-19 15:23:32.651 Timer[31067:707] Schedule task has executed with  this user info: To demo userInfo

NSTImer重复执行任务的更多相关文章

  1. remove name="ProxyModule“会导致重复执行

    <?xml version="1.0" encoding="utf-8"?> <!-- 有关如何配置 ASP.NET 应用程序的详细信息,请访 ...

  2. jquery 实现重复点击一个元素时不重复执行效果

    jquery 实现重复点击一个元素时不重复执行效果 这需要用到jquery的stop方法 实例 停止当前正在运行的动画: $("#stop").click(function(){ ...

  3. Spring的quartz定时器同一时刻重复执行二次的问题解决

    最近用Spring的quartz定时器的时候,发现到时间后,任务总是重复执行两次,在tomcat或jboss下都如此. 打印出他们的hashcode,发现是不一样的,也就是说,在web容器启动的时候, ...

  4. jquery click点击事件重复执行多次

    $("button[name^='privateBtn']").click(function(){ alert('demo'); //接触绑定.避免重复执行 $("but ...

  5. jQuery使用伪递归重复执行动画

    使用setInterval()来重复执行动画,会因为动画执行过程的时候,setInterval()的时间依然是在走的,所以会导致动画的调用时间不理想,因此只能使用递归来重复执行动画. // 首页LOG ...

  6. 使用定时器实现JavaScript的延期执行或重复执行

    使用定时器实现JavaScript的延期执行或重复执行 window 对象提供了两个方法来实现定时器的效果,分别是window.setTimeout()和 window.setInterval.其中前 ...

  7. Linux重复执行上条命令

    Linux系统下Shell重复执行上条命令的 4 种方法: 1.使用上方向键,并回车执行.2.按 !! 并回车执行.3.输入 !-1 并回车执行.4.按 Ctrl+P 并回车执行.

  8. java之生成可重复执行的sql脚本

    在实际项目开发过程中,sql脚本需要多次执行.而一般的DML和DDL语句一般只能执行一次,再次执行执行时就会报错(操作对应已存在/不存在),所以必须将sql脚本生成可重复执行的.本文共分为4部分:1. ...

  9. 可重复执行的SQL Script

    问题 在工作中偶尔会遇到这样的问题:SQL script重复执行时会报错. 理想的状态下,SQL script跑一遍就够了,是不会重复执行的,但是实际情况往往很复杂. 比如Dev同学在开发时在A环境把 ...

随机推荐

  1. Python 中使用optparse进行参数解析

    使用过Linux/Unix的人都会知道,命令行下的很多命令都需要参数,在C语言中添加和解析参数比较繁琐.Python中提供了optparse模块可以非常方便地处理命令行参数.   1  命令行参数的样 ...

  2. linux云计算集群架构学习笔记:命令查看文件内容

    查看文件内容 1.cat 命令 作用:查看文件内容 语法:cat 文件名 2. more 命令 作用:分页查看文件内容 语法:more  文件名 例:more /etc/passwd 按下回车刷新一行 ...

  3. CF Pangram

    Pangram time limit per test 2 seconds memory limit per test 256 megabytes input standard input outpu ...

  4. [改善Java代码]不同的列表选择不同的遍历方法

    一.场景: 我们来看一个场景,统计一个省的各科高考科目考试的平均分. 当然使用数据库中的一个SQL语句就能求出平均值,不过这个不再我们的考虑之列,这里只考虑使用纯Java的方式来解决.(由于我的机器配 ...

  5. XShell提示Connection closed by foreign host的问题 和 路由器分配IP的规则

    情况是这样的: VMware中有三个Linux机器分别是crxy99(192.168.1.99),crxy100(192.168.1.100),crxy101(192.168.1.101),crxy1 ...

  6. 关于修改Eclipse工作空间对应的文件夹名称之后的处理.

    把文件夹名字从"xhkong"变成"xhkong(maintenance5.6)"之后打开这个工作空间. 导入git仓库我发现了一个之前没有发现的小技巧. 导入 ...

  7. hdu 4605 线段树与二叉树遍历

    思路: 首先将所有的查询有一个vector保存起来.我们从1号点开始dfs这颗二叉树,用线段树记录到当前节点时,走左节点的有多少比要查询该节点的X值小的,有多少大的, 同样要记录走右节点的有多少比X小 ...

  8. 转:Nginx+ffmpeg的HLS开源服务器搭建配置及开发详解

    转:http://itindex.net/detail/51186-nginx-ffmpeg-hls 本文概述: 至目前为止,HLS 是移动平台上非常重要并十分流行的流媒体传输协议.做移动平台的流媒体 ...

  9. css3 多列布局记

    css3 多列布局 多列布局属性: columns:column-widht和column-count的缩写. column-width:定义每列列宽度. column-count:定义分列列数. c ...

  10. 基本STRUTS标签-学习笔记-Bean标签

    <bean:include> 和标准的JSP标签<jsp:include>很相似,都可以用来包含其他Web资源的内容,区别在于<bean:include>标签把其它 ...