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


当前回答

就像这样:

NSTimer *timer;

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

其他回答

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

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

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

可可定时器编程主题 线程编程指南

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

计时器 使用定时器

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

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

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

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

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

[myTimer invalidate];
myTimer = nil;

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

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

Because the run loop maintains the timer, from the perspective of memory management there's typically no need to keep a reference to a timer after you’ve scheduled it. Since the timer is passed as an argument when you specify its method as a selector, you can invalidate a repeating timer when appropriate within that method. In many situations, however, you also want the option of invalidating the timer—perhaps even before it starts. In this case, you do need to keep a reference to the timer, so that you can send it an invalidate message whenever appropriate. If you create an unscheduled timer (see “Unscheduled Timers”), then you must maintain a strong reference to the timer (in a reference-counted environment, you retain it) so that it is not deallocated before you use it.

#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;

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

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

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为静态的效率。

添加一小时组件就可以了,不需要午夜测试(链接)