pbootcms网站模板|日韩1区2区|织梦模板||网站源码|日韩1区2区|jquery建站特效-html5模板网

iOS中GCD定時器詳解

?CADisplayLink、NSTimer是基于RunLoop機制的,如果RunLoop的任務過于繁重,有可能會導致前兩個定時器不準時,這篇文章主要介紹了iOS中GCD定時器的相關知識,需要的朋友可以參考下

前言:CADisplayLink、NSTimer 不準時

?CADisplayLink、NSTimer是基于RunLoop機制的,如果RunLoop的任務過于繁重,有可能會導致前兩個定時器不準時。

舉個例子:

?加入我們創建了一個NSTimer定時器,每1秒鐘做任務。那么,什么時候執行NSTimer呢?
?是在RunLoop跑圈的過程中執行NSTimer定時器,而RunLoop跑完一圈執行的時間不固定,也就導致有可能1秒鐘過去了,但是RunLoop還沒有執行到定時器的任務,那么,這就造成定時器有可能不準時。

一、GCD 定時器

?GCD是不依賴與RunLoop,是直接跟系統內核交互的。時間比較準確。

GCD 定時器簡單的使用:

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"begin");    
    // 隊列
    dispatch_queue_t queue = dispatch_get_main_queue();
    // 創建定時器
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    // 設置時間
    uint64_t start = 2.0;
    uint64_t interval = 1.0;
    dispatch_source_set_timer(timer,
                              dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC),
                              interval * NSEC_PER_SEC, 0);
    
    // 設置回調
    dispatch_source_set_event_handler(timer, ^{
        NSLog(@"111");
    });
    // 啟動定時器
    dispatch_resume(timer);
    
    self.timer = timer;
}

2022-07-05 17:42:46.674345+0800 Interview02-GCD定時器[13943:350556] begin
2022-07-05 17:42:48.675440+0800 Interview02-GCD定時器[13943:350556] 111
2022-07-05 17:42:49.675542+0800 Interview02-GCD定時器[13943:350556] 111
2022-07-05 17:42:50.675350+0800 Interview02-GCD定時器[13943:350556] 111
2022-07-05 17:42:51.674523+0800 Interview02-GCD定時器[13943:350556] 111

二、GCD 定時器的實現方案

第一步:封裝

#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface RHGCDTimer : NSObject

+ (NSString *)timerWithBlockTask:(void(^)(void))blockTask
                      star:(float)star
                  interval:(float)interval
                    repeat:(BOOL)repeat
                     async:(BOOL)async;

+ (void)cancelTask:(NSString *)name;

@end

NS_ASSUME_NONNULL_END
#import "RHGCDTimer.h"

static NSMutableDictionary *timersDict;
static dispatch_semaphore_t semaphore;

@implementation RHGCDTimer

+ (void)initialize
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timersDict = [NSMutableDictionary dictionary];
        semaphore = dispatch_semaphore_create(1);//創建一個信號量,只允許一個線程操作
    });
}

+ (NSString *)timerWithBlockTask:(void (^)(void))blockTask star:(float)star interval:(float)interval repeat:(BOOL)repeat async:(BOOL)async
{
    
    if (!blockTask || star<0 || (repeat && interval <= 0)) return nil;
    
    //創建隊列,隊列決定到時候任務是在哪個線程執行
    dispatch_queue_t queue = async ? dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL) : dispatch_get_main_queue();

    //創建一個定時器
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    /**
    dispatch_source_set_timer 上面的定時器
    dispatch_time_t start 開始時間  (typedef uint64_t dispatch_time_t;)
    uint64_t interval 間隔
    uint64_t leeway 誤差一般寫0
    */
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, star * NSEC_PER_SEC), interval *NSEC_PER_SEC, 0);

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);//信號量
    //定時器唯一標識
    static int i = 0;
    NSString *name = [NSString stringWithFormat:@"%d", i++];
    
    //放進字典,就會產生強引用
    timersDict[name] = timer;
    dispatch_semaphore_signal(semaphore);
    
    //設置回調
    dispatch_source_set_event_handler(timer, ^{
        blockTask();
        if (!repeat) {//如果非重復執行
            [self cancelTask:name];//取消定時器
        }
    });
    //啟動定時器
    dispatch_resume(timer);
    //GCD不需要銷毀
    return name;
}

+ (void)cancelTask:(NSString *)name
{
    if (name.length == 0) return;
    
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    
    dispatch_source_t timer = timersDict[name];
    if (!timer) return;
    dispatch_source_cancel(timer);
    [timersDict removeObjectForKey:name];
    
    dispatch_semaphore_signal(semaphore);
}

@end

第二步:使用

#import "ViewController.h"

#import "RHGCDTimer.h"

@interface ViewController ()

@property (copy, nonatomic) NSString *task;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.task = [RHGCDTimer timerWithBlockTask:^{
        NSLog(@"執行任務---%@", [NSThread currentThread]);
    } star:2.0 interval:1.0 repeat:YES async:YES];
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [RHGCDTimer cancelTask:self.task];
}

@end

第三步:測試驗證

2022-07-05 17:31:41.375918+0800 Interview02-GCD定時器[13519:337316] 執行任務---<_NSMainThread: 0x600002448880>{number = 1, name = main}
2022-07-05 17:31:42.375935+0800 Interview02-GCD定時器[13519:337316] 執行任務---<_NSMainThread: 0x600002448880>{number = 1, name = main}
2022-07-05 17:31:43.375871+0800 Interview02-GCD定時器[13519:337316] 執行任務---<_NSMainThread: 0x600002448880>{number = 1, name = main}

到此這篇關于iOS中GCD定時器詳解的文章就介紹到這了,更多相關iOS GCD定時器內容請搜索html5模板網以前的文章希望大家以后多多支持html5模板網!

【網站聲明】本站部分內容來源于互聯網,旨在幫助大家更快的解決問題,如果有圖片或者內容侵犯了您的權益,請聯系我們刪除處理,感謝您的支持!

相關文檔推薦

主站蜘蛛池模板: 超声骨密度仪-动脉硬化检测仪器-人体成分分析仪厂家/品牌/价格_南京科力悦 | 防堵吹扫装置-防堵风压测量装置-电动操作显示器-兴洲仪器 | 广东成考网-广东成人高考网 | 福州仿石漆加盟_福建仿石漆厂家-外墙仿石漆加盟推荐铁壁金钢(福建)新材料科技有限公司有保障 | 郑州大巴车出租|中巴车租赁|旅游大巴租车|包车|郑州旅游大巴车租赁有限公司 | 台湾阳明固态继电器-奥托尼克斯光电传感器-接近开关-温控器-光纤传感器-编码器一级代理商江苏用之宜电气 | 武汉印刷厂-不干胶标签印刷厂-武汉不干胶印刷-武汉标签印刷厂-武汉标签制作 - 善进特种标签印刷厂 | 振动筛-交叉筛-螺旋筛-滚轴筛-正弦筛-方形摇摆筛「新乡振动筛厂家」 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 中天寰创-内蒙古钢结构厂家|门式刚架|钢结构桁架|钢结构框架|包头钢结构煤棚 | 礼仪庆典公司,礼仪策划公司,庆典公司,演出公司,演艺公司,年会酒会,生日寿宴,动工仪式,开工仪式,奠基典礼,商务会议,竣工落成,乔迁揭牌,签约启动-东莞市开门红文化传媒有限公司 | 泉州陶瓷pc砖_园林景观砖厂家_石英砖地铺石价格 _福建暴风石英砖 | 北京律师咨询_知名专业北京律师事务所_免费法律咨询 | 铁盒_铁罐_马口铁盒_马口铁罐_铁盒生产厂家-广州博新制罐 | 北京森语科技有限公司-模型制作专家-展览展示-沙盘模型设计制作-多媒体模型软硬件开发-三维地理信息交互沙盘 | 100_150_200_250_300_350_400公斤压力空气压缩机-舰艇航天配套厂家 | 蔬菜配送公司|蔬菜配送中心|食材配送|饭堂配送|食堂配送-首宏公司 | 能耗监测系统-节能监测系统-能源管理系统-三水智能化 | 珠光砂保温板-一体化保温板-有釉面发泡陶瓷保温板-杭州一体化建筑材料 | 湖南档案密集架,智能,物证,移动,价格-湖南档案密集架厂家 | 广州活动策划公司-15+年专业大型公关活动策划执行管理经验-睿阳广告 | 房屋质量检测-厂房抗震鉴定-玻璃幕墙检测-房屋安全鉴定机构 | 电池挤压试验机-自行车喷淋-车辆碾压试验装置-深圳德迈盛测控设备有限公司 | 盐水蒸发器,水洗盐设备,冷凝结晶切片机,转鼓切片机,絮凝剂加药系统-无锡瑞司恩机械有限公司 | 地脚螺栓_材质_标准-永年县德联地脚螺栓厂家 | 糖衣机,除尘式糖衣机,全自动糖衣机,泰州市长江制药机械有限公司 体感VRAR全息沉浸式3D投影多媒体展厅展会游戏互动-万展互动 | 钢格栅板_钢格板网_格栅板-做专业的热镀锌钢格栅板厂家-安平县迎瑞丝网制造有限公司 | 水平垂直燃烧试验仪-灼热丝试验仪-漏电起痕试验仪-针焰试验仪-塑料材料燃烧检测设备-IP防水试验机 | 安平县鑫川金属丝网制品有限公司,防风抑尘网,单峰防风抑尘,不锈钢防风抑尘网,铝板防风抑尘网,镀铝锌防风抑尘网 | arch电源_SINPRO_开关电源_模块电源_医疗电源-东佑源 | 减速机_上海宜嘉减速机| 耐驰泵阀管件制造-耐驰泵阀科技(天津)有限公司 | 半容积式换热器_北京浮动盘管换热器厂家|北京亿丰上达 | 运动木地板厂家,篮球场木地板品牌,体育场馆木地板安装 - 欧氏运动地板 | 天津次氯酸钠酸钙溶液-天津氢氧化钠厂家-天津市辅仁化工有限公司 | 电销卡_稳定企业大语音卡-归属地可选-世纪通信 | 便携式XPDM露点仪-在线式防爆露点仪-增强型烟气分析仪-约克仪器 冰雕-冰雪世界-大型冰雕展制作公司-赛北冰雕官网 | 破碎机_上海破碎机_破碎机设备_破碎机厂家-上海山卓重工机械有限公司 | 好看的韩国漫画_韩漫在线免费阅读-汗汗漫画 | 智能楼宇-楼宇自控系统-楼宇智能化-楼宇自动化-三水智能化 | 东莞注册公司-代办营业执照-东莞公司注册代理记账-极刻财税 |