iOS GCD定时器的使用

97 篇文章 0 订阅

其实定时器我们有很多创建形式 NSTimer、GCD等,今天我来说一下GCD版本的定时器

首先,什么是GCD呢?

百度一查一大堆

Grand Central Dispatch(GCD) 是 Apple 开发的一个多核编程的较新的解决方法。

它主要用于优化应用程序以支持多核处理器以及其他对称多处理系统。

它是一个在线程池模式的基础上执行的并发任务。在 Mac OS X 10.6 雪豹中首次推出,也可在 iOS 4 及以上版本使用。

为什么使用GCD呢?

因为使用 GCD 有很多优势

1、GCD 可用于多核的并行运算;

2、GCD 会自动利用更多的 CPU 内核(比如双核、四核);

3、GCD 会自动管理线程的生命周期(创建线程、调度任务、销毁线程);

4、程序员只需要告诉 GCD 想要执行什么任务,不需要编写任何线程管理代码。

下面就是干活儿了,直接上代码(这里我们把定时器封装了一个类、SXGCDTimer类,方便使用)

.h文件


#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SXGCDTimer : NSObject

/// 创建定时器
/// @param start 延迟多久执行
/// @param interval 多久时间执行一次
/// @param repeats 是否重复
/// @param async 是否是主线成
/// @param completion 执行方法
+ (NSString *)timerWithStartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async completion:(void (^)(void))completion;

/// 创建定时器
/// @param target 当前累
/// @param selector 执行的方法
/// @param start 延迟多久执行
/// @param interval 时间间隔
/// @param repeats 是否重复
/// @param async 是否主主线程
+ (NSString *)timerWithTarget:(id)target selector:(SEL)selector StartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async;

/// 取消某个定时器,
/// @param timerID 定时器id,默认从1开始,每创建一个定时器 +1
+ (void)cancel:(NSString *)timerID;


@end

.m

//
//  SXGCDTimer.m
//  SamsungSecurity
//
//  Created by abox on 2020/12/17.
//  Copyright © 2020 abox. All rights reserved.
//

#import "SXGCDTimer.h"

@interface SXGCDTimer()
@end

@implementation SXGCDTimer
static int i = 0;
// 创建保存timer的容器
static NSMutableDictionary *timers;
dispatch_semaphore_t sem;

+ (void)initialize{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        timers = [NSMutableDictionary dictionary];
        sem = dispatch_semaphore_create(1);
    });
}

/// 创建定时器
/// @param target 当前累
/// @param selector 执行的方法
/// @param start 延迟多久执行
/// @param interval 时间间隔
/// @param repeats 是否重复
/// @param async 是否主主线程
+ (NSString *)timerWithTarget:(id)target selector:(SEL)selector StartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async{
    if (!target || !selector) {
        return nil;
    }
    return [self timerWithStartTime:start interval:interval repeats:repeats mainQueue:async completion:^{
        if ([target respondsToSelector:selector]) {
            [target performSelector:selector];
        }
    }];
}

/// 创建定时器
/// @param start 延迟多久执行
/// @param interval 多久时间执行一次
/// @param repeats 是否重复
/// @param async 是否是主线成
/// @param completion 执行方法
+ (NSString *)timerWithStartTime:(NSTimeInterval)start interval:(NSTimeInterval)interval repeats:(BOOL)repeats mainQueue:(BOOL)async completion:(void (^)(void))completion{
    if (!completion || start < 0 ||  interval <= 0) {
        return nil;
    }
    // 创建定时器
    dispatch_queue_t queue = !async ? dispatch_queue_create("gcd.timer.queue", NULL) : dispatch_get_main_queue();
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue );
    // 设置时间,从什么时候开始,间隔多少,下面相当于2s后开始,每隔一秒一次
    dispatch_source_set_timer(timer, dispatch_time(DISPATCH_TIME_NOW, start * NSEC_PER_SEC), interval * NSEC_PER_SEC, 0);
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    NSString *timerId = [NSString stringWithFormat:@"%d",i++];
    NSLog(@"timerId = = = = = =%@",timerId);
    timers[timerId]=timer;
    dispatch_semaphore_signal(sem);
    // 回调
    dispatch_source_set_event_handler(timer, ^{
        if (completion) {
            completion();
        }
        // 不重复执行就取消timer
        if (!repeats) {
            [self cancel:timerId];
        }
    });
    dispatch_resume(timer);
    
    return timerId;
}

/// 取消某个定时器,
/// @param timerID 定时器id,默认从1开始,每创建一个定时器 +1
+ (void)cancel:(NSString *)timerID{
    if (!timerID || timerID.length <= 0) {
        return;
    }
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
    dispatch_source_t timer = timers[timerID];
    if (timer) {
        dispatch_source_cancel(timer);
        [timers removeObjectForKey:timerID];
    }
    dispatch_semaphore_signal(sem);
}

@end

到此定时器就完成了,下面是如何使用

//开启定时器
[SXGCDTimer timerWithStartTime:0 interval:2 repeats:YES mainQueue:NO completion:^{
    NSLog(@"第一种");
}];
//取消定时器
[SXGCDTimer cancel:@"1"];

到此定时器就完成了

参考:https://www.jianshu.com/p/f24abac597ce

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王 哪跑!!!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值