我如何使用NSTimer?

如何使用NSTimer?谁能给我一步一步的指导?

531779 次浏览

就像这样:

NSTimer *timer;


timer = [NSTimer scheduledTimerWithTimeInterval: 0.5
target: self
selector: @selector(handleTimer:)
userInfo: nil
repeats: YES];

首先,我想让您注意一下Cocoa/CF文档(这总是一个很好的第一步)。苹果文档在每篇参考文章的顶部都有一个叫做“Companion Guides”的部分,它列出了所记录主题的指南(如果存在的话)。例如,对于NSTimer的文档列出了两个配套指南:

对于您的情况,定时器编程主题文章可能是最有用的,而线程主题与所记录的类相关,但不是最直接的相关。如果你看一看定时器编程主题的文章,它分为两部分:

  • 计时器
  • 使用定时器

对于采用这种格式的文章,通常有一个类的概述和它的用途,然后是如何上的一些示例代码来使用它,在本例中是“使用计时器”一节。有“创建和调度定时器”,“停止定时器”和“内存管理”部分。在本文中,可以这样创建一个定时的、不重复的计时器:

[NSTimer scheduledTimerWithTimeInterval:2.0
target:self
selector:@selector(targetMethod:)
userInfo:nil
repeats:NO];

这将创建一个计时器,在2.0秒后触发,并使用一个参数在self上调用targetMethod:,该参数是指向NSTimer实例的指针。

如果你想更详细地了解这个方法,你可以参考文档获取更多信息,但是关于代码也有解释。

如果你想停止一个重复的计时器(或在非重复计时器触发之前停止它),那么你需要保留一个指向创建的NSTimer实例的指针;通常这需要是一个实例变量,以便您可以在另一个方法中引用它。然后你可以在NSTimer实例上调用invalidate:

[myTimer invalidate];
myTimer = nil;

nil out实例变量也是一个很好的实践(例如,如果你的使计时器失效的方法被调用了不止一次,而实例变量还没有被设置为nil,并且NSTimer实例已经被释放,它将抛出异常)。

还要注意文章末尾关于内存管理的观点:

因为运行循环维护计时器,从内存管理的角度在你安排了一个定时器之后,通常不需要保持对它的引用。由于计时器是在指定它的方法作为选择器时作为参数传递的,因此您可以在该方法中适当的时候使重复计时器失效. 您可以在该方法中适当的时候使重复计时器失效。然而,在许多情况下,您还需要使计时器失效的选项——甚至可能在它开始之前。在这种情况下,您确实需要保留对计时器的引用,以便在适当的时候向它发送无效消息。如果您创建了一个未调度定时器(请参阅“未调度定时器”),那么您必须维护对该定时器的强引用(在引用计数环境中,您保留它),以便在使用它之前不会释放它。

有几种使用计时器的方法:

1) 定时定时器&使用选择器

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
target: self
selector:@selector(onTick:)
userInfo: nil repeats:NO];
  • 如果你将repeat设置为NO,计时器将在运行选择器之前等待2秒,之后它将停止;
  • 如果重复:YES,计时器将立即启动,并将每2秒重复调用选择器;
  • 要停止计时器,请调用计时器的-invalidate方法:[t invalidate];

作为旁注,与其使用不重复的计时器,并在指定的间隔后调用选择器,不如使用如下简单的语句:

[self performSelector:@selector(onTick:) withObject:nil afterDelay:2.0];

这将与上面的示例代码具有相同的效果;但如果你想每n次调用一次选择器,你可以使用重复的计时器:YES;

< / p >

2) self-scheduled计时器

NSDate *d = [NSDate dateWithTimeIntervalSinceNow: 60.0];
NSTimer *t = [[NSTimer alloc] initWithFireDate: d
interval: 1
target: self
selector:@selector(onTick:)
userInfo:nil repeats:YES];


NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer:t forMode: NSDefaultRunLoopMode];
[t release];
  • 这将创建一个计时器,该计时器将在您指定的自定义日期(在本例中为一分钟后)开始,并每一秒钟重复一次

    < /李>

3) 计划外定时器&使用调用

NSMethodSignature *sgn = [self methodSignatureForSelector:@selector(onTick:)];
NSInvocation *inv = [NSInvocation invocationWithMethodSignature: sgn];
[inv setTarget: self];
[inv setSelector:@selector(onTick:)];


NSTimer *t = [NSTimer timerWithTimeInterval: 1.0
invocation:inv
repeats:YES];

在那之后,你可以手动启动计时器,就像这样:

NSRunLoop *runner = [NSRunLoop currentRunLoop];
[runner addTimer: t forMode: NSDefaultRunLoopMode];
< p >

注意,onTick:方法看起来像这样:

-(void)onTick:(NSTimer *)timer {
//do smth
}

答案中缺少一个特定的时间,这里是下一个小时:

NSCalendarUnit allUnits = NSCalendarUnitYear   | NSCalendarUnitMonth |
NSCalendarUnitDay    | NSCalendarUnitHour  |
NSCalendarUnitMinute | NSCalendarUnitSecond;


NSCalendar *calendar = [[ NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];


NSDateComponents *weekdayComponents = [calendar components: allUnits
fromDate: [ NSDate date ] ];


[ weekdayComponents setHour: weekdayComponents.hour + 1 ];
[ weekdayComponents setMinute: 0 ];
[ weekdayComponents setSecond: 0 ];


NSDate *nextTime = [ calendar dateFromComponents: weekdayComponents ];


refreshTimer = [[ NSTimer alloc ] initWithFireDate: nextTime
interval: 0.0
target: self
selector: @selector( doRefresh )
userInfo: nil repeats: NO ];


[[NSRunLoop currentRunLoop] addTimer: refreshTimer forMode: NSDefaultRunLoopMode];

当然,用类所需的方法替换“doRefresh”

尝试创建一次日历对象,并使allUnits为静态的效率。

添加一个小时组件工作得很好,不需要午夜测试(链接)

#import "MyViewController.h"


@interface MyViewController ()


@property (strong, nonatomic) NSTimer *timer;


@end


@implementation MyViewController


double timerInterval = 1.0f;


- (NSTimer *) timer {
if (!_timer) {
_timer = [NSTimer timerWithTimeInterval:timerInterval target:self selector:@selector(onTick:) userInfo:nil repeats:YES];
}
return _timer;
}


- (void)viewDidLoad
{
[super viewDidLoad];


[[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}


-(void)onTick:(NSTimer*)timer
{
NSLog(@"Tick...");
}


@end
NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:@selector(timerCalled) userInfo:nil repeats:NO];


-(void)timerCalled
{
NSLog(@"Timer Called");
// Your Code
}