基于NSTimer的倒计时

14 篇文章 0 订阅
14 篇文章 2 订阅
基于NSTimer的倒计时

        开发过程中,有时会遇到倒计时的需求。体现在界面上,一般提示用户还剩多长时间,倒计时结束后再触发一个动作。

        OSX或IOS开发过程中,我所知道的,实现倒计时功能的有两种方法,一种是使用NSTimer来实现,第二种是使用GCD(配合dispatch_source_t相关类)的方法来实现。

        本文主要涉及第一种方法,基于NSTimer来实现倒计时的功能。
        设计时大概从如下方面来考虑:

   1. 倒计时时间(多长时间的倒计时)
   2. 每次倒计时时候的通知(回调函数)
   3. 保证线程安全(创建与取消在同一个线程内)

        考虑的再详细一点的话,倒计时时间进一步细分,体现到倒计时次数与频率上面,是60次频率为1秒每次,还是10次频率为0.5秒。NSTimer的刷新频率有限制,间隔不能太小,太小了也没意义,不可能比CPU的调度间隔还小了吧。另外NSTimer也不是绝对的精确,据说50-100毫秒,没有考证过。

        基于上述原则了,定义一个类,实现倒计时的功能。

@interface CountDownTimer : NSObject

- (void)startTimer:(NSTimeInterval)timeInterval
       withTarget:(id)target
      withSelector:(SEL)selector;
- (void)cancelTimer;

@end
static dispatch_queue_t countDownTimer_queue() {
    static dispatch_queue_t countDownTimer_queue;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        countDownTimer_queue = dispatch_queue_create("countDownTimerQueue", DISPATCH_QUEUE_SERIAL);
    });

    return countDownTimer_queue;
}

@interface CountDownTimer()

@property (nonatomic) NSTimer *timer;
@property (nonatomic) id target;
@property (assign) NSTimeInterval countTime;
@property (nonatomic) SEL selector;

@end

@implementation CountDownTimer

- (void)startTimer:(NSTimeInterval)timeInterval
        withTarget:(id)target
      withSelector:(SEL)selector
{
    dispatch_async(countDownTimer_queue(), ^{
        if (self.timer && self.timer.isValid) {
            [self.timer invalidate];
            self.timer = nil;
        }
        if (!self.timer) {
            _countTime = timeInterval;
            _target = target;
            _selector = selector;
            self.timer = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:1.0f target:self selector:@selector(countDown:) userInfo:nil repeats:YES];

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

    });

}

- (void)countDown:(NSTimer*)timer
{
    if (self.target && self.selector && [self.target respondsToSelector:self.selector]) {
        [self.target performSelectorOnMainThread:self.selector
                               withObject:[NSNumber numberWithDouble:self.countTime]
                            waitUntilDone:NO];
    }
    self.countTime--;
    if (self.countTime <= -1) {
        [self cancelTimer];
    }
}

- (void)cancelTimer {
    dispatch_sync(countDownTimer_queue(), ^{
        [self.timer invalidate];
         self.timer = nil;
    });

}

- (void)dealloc {
    [self cancelTimer];
}

@end

        转载请注明出处:http://blog.csdn.net/skynullcode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值