iOS GCD定时器的使用

本文介绍了如何使用GCD(Grand Central Dispatch)创建定时器,包括倒计时定时器和重复定时器。通过dispatch_source_create()、dispatch_source_set_timer()等函数设置和启动定时器,并提供了创建和停止定时器的封装方法。示例代码展示了在iOS应用中使用GCD定时器进行3秒倒计时和0.5秒间隔的重复计时操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

GCD定时器

使用dispatch_source_t定时器(重复定时器和倒计时定时器)。主要函数有:

  • 创建定时器 dispatch_source_create()
  • 设置定时器时间 dispatch_source_set_timer()
  • 设置定时器回调 dispatch_source_set_event_handler()
  • 启动定时器 dispatch_resume()
  • 取消定时器 dispatch_source_cancel()

相关函数库路径:Xcode -> iOS 15.0 -> usr/include -> dispatch -> source.h

dispatch_source_t相关函数文件

1. GCD定时器的使用
//
//  ViewController.m
//
//  Created by wangzhi on 2022/7/15.
//  Copyright © 2022 BTStudio. All rights reserved.
//

#import "ViewController.h"
#import "GCDTimer.h"

@interface ViewController ()

@property (nonatomic, strong) GCDTimer timer;
@property (nonatomic, assign) NSInteger time;

@end

@implementation QYSoftenerViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    __weak typeof(self) weakSelf = self;
    
    self.time = 0;
    
    
    // 1. 倒计时 (倒计时3s)
    NSLog(@"GCDTimer_倒计时开始...");
    CreateGCDCountdownTimer(3, ^{
        NSLog(@"GCDTimer_倒计时结束!");
    });
    // 控制台打印:
    // 2022-07-15 13:33:30.052590+0800 Demo[85963:4226935] GCDTimer_倒计时开始...
    // 2022-07-15 13:33:33.054097+0800 Demo[85963:4227534] GCDTimer_倒计时结束!
    
    
    // 2. 计时器 (计时3s,每隔0.5s调用一次)
    // 提示: 
    // - 创建重复计时器需要强引用,否则不会执行回调;
    // - 创建倒计时计时器可以强引用,也可不引用,都会执行回调;
    NSLog(@"GCDTimer_计时器开始...");
    self.timer = CreateGCDRepeatTimer(0.5, ^{
        NSLog(@"GCDTimer_计时器......");
        
        self.time++;
        if (self.time == 6) {
            CancelGCDRepeatTimer(weakSelf.timer);
        }
    });
    // 控制台打印:
    // 2022-07-15 13:41:12.114587+0800 Demo[86030:4230591] GCDTimer_计时器开始...
    // 2022-07-15 13:41:12.615352+0800 Demo[86030:4230789] GCDTimer_计时器......
    // 2022-07-15 13:41:13.115763+0800 Demo[86030:4230875] GCDTimer_计时器......
    // 2022-07-15 13:41:13.616101+0800 Demo[86030:4230875] GCDTimer_计时器......
    // 2022-07-15 13:41:14.116064+0800 Demo[86030:4230875] GCDTimer_计时器......
    // 2022-07-15 13:41:14.616043+0800 Demo[86030:4230875] GCDTimer_计时器......
    // 2022-07-15 13:41:15.116007+0800 Demo[86030:4230875] GCDTimer_计时器......
}
2. GCD定时器源代码

GCDTimer类,使用时导入该类即可。

函数 dispatch_time(dispatch_time_t when, int64_t delta) 的参数介绍:
  • 第一个参数 when :一般是DISPATCH_TIME_NOW,表示从现在开始
  • 第二个参数 delta :延时时间,这里要特别注意的是delta参数是“纳秒”!
函数 dispatch_source_set_timer(dispatch_source_t source, dispatch_time_t start, uint64_t interval, uint64_t leeway) 的参数介绍:
  • 第一个参数 source :被设置的定时器
  • 第二个参数 start :开始时间
  • 第三个参数 interval :时间间隔,注意是“纳秒”!
  • 第四个参数 leeway :误差,置0就好
2.1 GCDTimer.h
//
//  GCDTimer.h
//
//  Created by wangzhi on 2022/7/15.
//  Copyright © 2022 BTStudio. All rights reserved.
//

#import <Foundation/Foundation.h>

/**
 * 定时器类型
 */
typedef dispatch_source_t GCDTimer;


/**
 创建重复定时器
 
 @param timeInterval 时间间隔,单位: s ( <= 0时,则置为1)
 @param handler 定时器触发回调
 @return 定时器
 */
GCDTimer CreateGCDRepeatTimer(NSTimeInterval timeInterval, dispatch_block_t handler);

/**
 停止定时器
 
 @param timer 定时器
 */
void CancelGCDRepeatTimer(GCDTimer timer);


/**
 创建倒计时定时器
 
 @param time 倒计时时长,单位: s ( <= 0时,则置为1)
 @param handler 定时器触发回调
 @return 定时器
 */
GCDTimer CreateGCDCountdownTimer(NSTimeInterval time, dispatch_block_t handler);

/**
 停止定时器
 
 @param timer 定时器
 */
void CancelGCDCountdownTimer(GCDTimer timer);
2.2 GCDTimer.m
//
//  GCDTimer.m
//
//  Created by wangzhi on 2022/7/15.
//  Copyright © 2022 BTStudio. All rights reserved.
//

#import "GCDTimer.h"

/**
 创建重复定时器
 
 @param timeInterval 时间间隔,单位: s ( <= 0时,则置为1)
 @param handler 定时器触发回调
 @return 定时器
 */
GCDTimer CreateGCDRepeatTimer(NSTimeInterval timeInterval, dispatch_block_t handler) {
    // 创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 1. 创建定时器
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    // 2. 设置时间
    /**
     * 计时的时间间隔(如果 <= 0, 则置为1)
     */
    uint64_t time_interval_ms = timeInterval <= 0 ? 1000 : (timeInterval * 1000);
    /**
     * 开始时间
     * 第一个参数 when: 一般是DISPATCH_TIME_NOW,表示从现在开始
     * 第二个参数 delta: 延时时间,这里要特别注意的是delta参数是"纳秒"!
     */
    dispatch_time_t start_time = dispatch_time(DISPATCH_TIME_NOW, time_interval_ms * NSEC_PER_MSEC);
    /**
     * 第一个参数: 被设置的定时器
     * 第二个参数: 开始时间
     * 第三个参数: 时间间隔,注意是"纳秒"!
     * 第四个参数: 误差,置0就好
     */
    dispatch_source_set_timer(timer, start_time, time_interval_ms * NSEC_PER_MSEC, 0);
    dispatch_source_set_event_handler(timer, ^{
        // 执行回调
        if (handler) {
            handler();
        }
    });
    // 3. 启动定时器
    dispatch_resume(timer);
    return timer;
}

/**
 停止定时器
 
 @param timer 定时器
 */
void CancelGCDRepeatTimer(GCDTimer timer) {
    if (timer) {
        dispatch_source_cancel(timer);
        timer = nil;
    }
}


/**
 创建倒计时定时器

 @param time 倒计时时长,单位: s ( <= 0时,则置为1)
 @param handler 定时器触发回调
 @return 定时器
 */
GCDTimer CreateGCDCountdownTimer(NSTimeInterval time, dispatch_block_t handler) {
    // 创建队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 1. 创建定时器
    dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
    // 2. 设置时间
    /**
     * 计时的时间间隔(如果 <= 0, 则置为1)
     */
    uint64_t time_interval_ms = time <= 0 ? 1000 : (time * 1000);
    /**
     * 开始时间
     * 第一个参数 when: 一般是DISPATCH_TIME_NOW,表示从现在开始
     * 第二个参数 delta: 延时时间,这里要特别注意的是delta参数是"纳秒"!
     */
    dispatch_time_t start_time = dispatch_time(DISPATCH_TIME_NOW, time_interval_ms * NSEC_PER_MSEC);
    /**
     * 第一个参数: 被设置的定时器
     * 第二个参数: 开始时间
     * 第三个参数: 时间间隔,注意是"纳秒"!
     * 第四个参数: 误差,置0就好
     */
    dispatch_source_set_timer(timer, start_time, time_interval_ms * NSEC_PER_MSEC, 0);
    dispatch_source_set_event_handler(timer, ^{
        // 停止定时器
        dispatch_source_cancel(timer);
        
        // 执行回调
        if (handler) {
            handler();
        }
    });
    // 3. 启动定时器
    dispatch_resume(timer);
    return timer;
}

/**
 停止定时器
 
 @param timer 定时器
 */
void CancelGCDCountdownTimer(GCDTimer timer) {
    if (timer) {
        dispatch_source_cancel(timer);
        timer = nil;
    }
}
### 如何配置 Spring Boot 自动打印 MyBatis SQL 语句 为了使 Spring Boot 应用程序能够自动打印由 MyBatis 生成的 SQL 语句,可以通过多种方式进行设置。以下是几种常见方法: #### 方法一:通过 `application.yml` 文件配置 可以在项目的 `application.yml` 或者 `application.properties` 中添加特定于 MyBatis 的属性来启用 SQL 日志记录功能。 对于 YAML 格式的配置文件,可以这样写入: ```yaml mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ``` 此配置项会指示 MyBatis 使用标准输出流作为日志实现工具[^2]。 #### 方法二:修改 MyBatis XML 配置文件中的 `<settings>` 节点 如果项目中有单独定义的 MyBatis XML 配置文件,则可在该文件内加入如下片段以激活 SQL 打印功能: ```xml <configuration> <settings> <!-- 启用SQL日志 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> </configuration> ``` 这种方式同样能有效触发 SQL 查询的日志输出至控制台[^4]。 #### 方法三:利用内置的日志框架进行更灵活的日志管理 考虑到实际生产环境中可能需要更加精细地控制日志级别以及目的地等因素,推荐采用基于现有 Java 日志库(如 Logback、Log4j 等)的方式来处理这个问题。例如,在使用 SLF4J 和 Logback 组合的情况下,只需调整相应的 logger 设置即可满足需求: ```properties logging.level.com.example.mapper=DEBUG ``` 这里假设所有的 Mapper 接口都位于包路径 `com.example.mapper` 下面;将这些接口的日志等级设为 DEBUG 就可以让它们发出详细的执行信息,包括完整的 SQL 文本[^5]。 以上三种方案均可达成目的,具体选用哪一种取决于个人偏好和技术栈的选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值