iOS 创建定时器的三种方法

小编的语言表达能力不是很强,希望看到的大佬能理解我的意思,如果有什么问题欢迎各位大佬评论区留言。

定时器在iOS项目中用到的十分的频繁,这里给大家提供三种创建定时器的方法

代码中的 ZLTimerTarget 和 ZLTimerProxyTarget可以在demo中查看。
demo下载地址

demo中包含了定时器的释放和会造成循环引用问题的解决,ZLTimerProxyTarget,ZLTimerTarget在target文件夹中。

Tip:NSTimer和CADisplayLink 都是依赖于RunLoop去实现的,但是我们都知道,RunLoop底层是循环的在做一些source0、source1、timer、Observe这几个事件,一旦在处理非timer事件中有耗时操作的话,会影响到timer的定时任务,所以,NSTimer和CADisPlayLink在某些场景中,定时任务不是很准时的。但是CGD就不会,GCD不依赖于RunLoop,是直接和内核挂钩,时间比较准。

以下是创建三种定时器的方法:

//
//  MemoryManageController.m
//  TZLDemo
//
//  Created by TZL on 2021/1/8.
//  Copyright © 2021 Tzl. All rights reserved.
//

#import "MemoryManageController.h"
#import "ZLTimerTarget.h"
#import "ZLTimerProxyTarget.h"///NSProxy转发
@interface MemoryManageController ()
/**  定时器  **/
@property (nonatomic , strong)NSTimer  *timer;
/**  定时器2  **/
@property (nonatomic , strong)CADisplayLink  *caDis;
/**  定时器3  **/
@property (nonatomic , strong)dispatch_source_t gcdTimer;


@end

@implementation MemoryManageController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.view.backgroundColor = UIColor.whiteColor;
    
    ///创建定时器
//    [self createNSTimer];
    [self createCAD];
//    [self createGCDTimer];
}
#pragma mark - --------- NSTimer 创建 ---------
- (void)createNSTimer{
    ///这里相当于走了msg_send消息发送机制,会走三大步
//    self.timer = [NSTimer timerWithTimeInterval:1 target:[ZLTimerTarget initWihtTarget:self] selector:@selector(test) userInfo:nil repeats:YES];
    
    ///这里就直接走最后一步的消息转发,通过消息签名去执行方法 !!!!会走消息转发!!!!!
    self.timer = [NSTimer timerWithTimeInterval:1 target:[ZLTimerProxyTarget initWithTarget:self] selector:@selector(test) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
}

#pragma mark - --------- CAD创建定时器  ---------
///一秒60帧左右
- (void)createCAD{
    //    self.caDis = [CADisplayLink displayLinkWithTarget:[ZLTimerTarget initWithTarget:self] selector:@selector(test)];;
        ///这里就直接走最后一步的消息转发,通过消息签名去执行方法 !!!!会走消息转发!!!!!
    self.caDis = [CADisplayLink displayLinkWithTarget:[ZLTimerProxyTarget initWithTarget:self] selector:@selector(test)];
    [self.caDis addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
}


#pragma mark - --------- GCD创建定时器  ---------
- (void)createGCDTimer{

    NSLog(@"开始");
    dispatch_queue_t queue = dispatch_queue_create("当前队列", DISPATCH_QUEUE_CONCURRENT);
//    ///创建一个定时器
    self.gcdTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);///queue是指的在哪个队列中做事情
    /**
     DISPATCH_TIME_NOW :立马执行  dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC) (这个是延迟两秒后执行)
     
     intervalInSeconds:间隔多少秒做事情
     
     leewayInSeconds :传0即可 回旋参数
     **/
    dispatch_source_set_timer(self.gcdTimer,
                              dispatch_time(DISPATCH_TIME_NOW, 2*NSEC_PER_SEC) ,
                              1 * NSEC_PER_SEC,
                              0);

    /** 执行的任务   **/
    dispatch_source_set_event_handler(self.gcdTimer, ^{
        NSLog(@"sss");
    });
    
//    /**
//     执行任务
//     dispatch_function_t  _Nullable handler:这里要传一个C语言的函数:  void (*dispatch_function_t)(void *_Nullable)
//     **/
//    dispatch_source_set_event_handler_f(self.gcdTimer, xxx);
    ///开启定时器
    dispatch_resume(self.gcdTimer);
}
/////C语言的执行方法
//void xxx(void *param){
//    NSLog(@"sss");
//};



#pragma mark - --------- 私有方法  ---------
///定时任务
- (void)test{
    NSLog(@"输出了");
}

-(void)dealloc{
    NSLog(@"%s",__func__);
    ///定时器要销毁
    [self.timer invalidate];
    [self.caDis invalidate];
}



@end

你可能感兴趣的:(iOS 创建定时器的三种方法)