Objective-C 编程:NSTimer

定时器:让程序定时执行某一个方法。

用 NSTimer 封装的定时器示例

MyTimeCounter.h 文件

#import <Foundation/Foundation.h>

@protocol MyTimeCounterDelegate <NSObject>
// 外部调用这个类需要实现的代理方法,用于返回当前计时的时间
-(void)currentTime:(NSUInteger)time;
@end

// 自定义的定时器类
@interface MyTimeCounter : NSObject

@property (nonatomic, strong) id<PATimeCounterDelegate>delegate;

- (void)start;
- (void)stop;
- (void)pause;
- (void)continue;

@end

MyTimeCounter.m 文件

#import "MyTimeCounter.h"

@interface MyTimeCounter()

@property (nonatomic, assign) NSUInteger count; // 全局属性,用于记录当前的秒数
@property (nonatomic, strong) NSTimer *timer;

@end

@implementation MyTimeCounter

// 开始计时
- (void)start {
    [self start]; // 重置计时器
    
    /* 方法作用:每隔1秒执行指定方法
     *
     * 参数说明:
     * TimeInterval : 执行之前等待的时间。比如设置成 1.0,就代表 1 秒后执行方法。
     * target : 需要执行方法的对象。
     * selector : 需要执行的方法。
     * userInfo : 用户信息
     * repeats : 是否需要循环
     */
    self.timer = [NSTimer scheduledTimerWithTimeInterval:1.0f
                                                  target:self
                                                selector:@selector(repeatShowTime:)
                                                userInfo:nil
                                                 repeats:YES];
}

- (void)repeatShowTime:(NSTimer *)tempTimer {
    _count ++;
    
    // 返回当前记录的时间
    if (_delegate && [_delegate respondsToSelector:@selector(currentTime:)]) {
        [_delegate currentTime:_count];
    }
}

// 停止计时
- (void)stop {
    // 如果已经存在 timer 对象,则释放
    if (self.timer) {
        [self.timer invalidate]; // 释放计时器
        self.timer = nil;
    }
    _count = 0;
}

// 暂停
- (void)pause {
    [self.timer setFireDate:[NSDate distantFuture]];
}

// 继续
- (void)continue {
    [self.timer setFireDate:[NSDate date]];
}

// 销毁
- (void)dealloc {
    if (self.timer) {
        [self.timer invalidate];
        self.timer = nil;
    }
}

@end

外部调用

#import "MyTimeCounter.h"

// 默认倒计时 15s
static int const KCountDown = 15;

//...

@property (nonatomic, strong) MyTimeCounter *timeManager; // 倒计时管理器

//...

// Lazy loading
- (PATimeCounter *)timeManager{
    if (!_timeManager) {
        _timeManager = [[PATimeCounter alloc] init];
        _timeManager.delegate = self;
    }
    return _timeManager;
}

- (void)myFunction {
  [self.timeManager start]; // 开始倒计时
  
  // ...
  
  [self.timeManager stop]; // 结束倒计时
}

#pragma mark - MyTimeCounterDelegate

// 倒计时管理器
- (void)currentTime:(NSUInteger)time {
    if (time != KCountDown) {
        // 主线程更新 UI
        __weak __typeof(self)weakSelf = self;
        dispatch_async(dispatch_get_main_queue(), ^{
            weakSelf.timeLabel.text = [NSString stringWithFormat:@"%d", KCountDown - time];
        });
    } else {
        _isTimeOut = YES;
    }
}

通过 GCD 实现的 60s 倒计时示例

// 重复执行事件
__block int timeout = 60; // 倒计时时间
NSTimeInterval intervalInSeconds = 1.0; // 执行时间间隔,1秒

// 全局队列
dispatch_queue_t queue = dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0);

// 计时器
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, intervalInSeconds * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
dispatch_source_set_event_handler(timer, ^{
    // 执行的事件
    if (timeout <= 0) {
        dispatch_source_cancel(timer);
        dispatch_async(dispatch_get_main_queue(), ^{
            // 主队列执行
            
        });
    } else {
        dispatch_async(dispatch_get_main_queue(), ^{
            // 主队列执行
            
        });
    }
    timeout --;
});
dispatch_resume(timer);

开源的第三方框架

参考 GitHub:https://github.com/search?q=iOS+Countdown

参考

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Runloop定时器的应用及关闭iOS NSTimer 定时器用法总结 1.定时器的创建 参数1:时间间隔(定时的...
    Barry_小闪阅读 2,299评论 0 0
  • 一. NSTimer NSTimer的初始化方法有以下几种: 会自动启动, 并加入* MainRunloop*的*...
    codeshow阅读 3,564评论 0 0
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,723评论 4 61
  • 我这个人吧,最喜欢一时兴起,当然我也知道,我不把自己的思绪理一理,特别容易被情绪或别人带偏。那么,我的瑜伽之路整理...
    曾曾的麻麻阅读 1,787评论 1 1
  • 早餐是一天中最关键的进餐时段,关系到人一天的精气神是否充沛,所以只有吃好早餐才能保证有良好的精神状态工作,所以早餐...
    美丽大霞阅读 3,477评论 0 0

友情链接更多精彩内容