iOS-OC定时器大总结(NSTimer、performSelector、GCD、dispatch_source_t、CADisplayLink)

前言

 在iOS中延迟执行的需求很常见,比如我们在首页弹出一个可关闭的广告,我们需要图片加载完成或者UI加载完成以后才展示弹窗广告。

 我在这里总结一下在iOS中常用的一些延迟执行的方法。

NSTimer

 定时器方法大家应该会首先想到,我们也经常用到,比如在发送验证码设置一个60s的倒计时。PS:NSTimer有8中创建方法,我以前整理过,移步参看《 iOS-NSTimer的前世今生(NSTimer不同创建方式的区别)》。

 我这里提供一种方法作为示例:

_myTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(myTimer) userInfo:nil repeats:YES];

取消定时器方法

[_myTimer invalidate];

performSelector

 performSelector: withObject:是iOS的一种方法调用方式,他可以向一个对象传递任何消息,而且不需要在编译的时候声明这些方法。所以这个也是runtime的一种应用方式。

 performSelector有无参数和有参数传递方式,这里我以一个参数的方式进行举例:

[self performSelector:@selector(loginWasSuccessful:) withObject:@"OneParameter"];
响应函数
- (void)loginWasSuccessful:(NSString *)parameter{
    NSLog(@"parameter: %@", parameter);
 }

取消方法

[NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(loginWasSuccessful:) object:nil];

注意:函数名要保持一致,不然取消失败。

GCD

GCD在项目中使用非常简单,相信大家用的也比较多,GCD在执行的时候有两种Dispatch Queue,一种是Serial Dispatch Queue串行调度队列,这个是等待现在执行中的事件处理结束,另一种是Concurrent Dispatch Queue并发调度队列,这个是不等待现在执行中的事件处理结束。

使用示例:

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
    [self.chatInputTool showInputView];//弹出评论框
 });

 dispatch_after并没有提供取消的方法。

dispatch_source_t

 默认是重复执行的,我们可以在事件毁掉中通过dispatch_source_cancel来取消来达到只执行一次的目的。

@property (strong,nonatomic)dispatch_source_t sourceTimer;
//dispatch_source_t
 - (void)createDispatch_source_t{
 
 //创建全局队列
 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 
 //使用全局队列创建计时器
 _sourceTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
 
 //定时器延迟时间
 NSTimeInterval delayTime = 1.0f;
 
 //定时器间隔时间
 NSTimeInterval timeInterval = 1.0f;
 
 //设置开始时间
 dispatch_time_t startDelayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayTime * NSEC_PER_SEC));
 
 //设置计时器
 dispatch_source_set_timer(_sourceTimer,startDelayTime,timeInterval*NSEC_PER_SEC,0.1*NSEC_PER_SEC);
 
 //执行事件
 dispatch_source_set_event_handler(_sourceTimer,^{
 
    //销毁定时器
    //dispatch_source_cancel(_myTimer);
 });
 
 //启动计时器
 dispatch_resume(_sourceTimer);
 }

CADisplayLink

CADisplayLink也是一个定时器,每隔几毫米刷新一次屏幕。CADisplayLink是一个能让我们可以和屏幕刷新率相同的频率将内容画到屏幕上。我们在项目中创建CADisplayLink并把它添加到RunLoop中,并给他提供一个target和selector。
 PS:《iOS[QuartzCore框架]CADisplayLink篇

使用示例:

@property (strong,nonatomic)CADisplayLink *displaylinkTimer;
_displaylinkTimer = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleDisplayLink:)];
 [_displaylinkTimer addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode];
 
 - (void)handleDisplayLink:(CADisplayLink *)displaylinkTimer{
 NSLog(@"%s-----%ld",__func__,displaylinkTimer.preferredFramesPerSecond);
 }
销毁定时器
[_displaylinkTimer invalidate];
 _displaylinkTimer = nil;

说明:当把CADisplayLink对象add到runloop中后,selector就能被周期性调用,类似于重复的NSTimer被启动了;执行invalidate操作时,CADisplayLink对象就会从runloop中移除,selector调用也随即停止,类似于NSTimer的invalidate方法。

结束语

 欢迎各位大神补充!

欢迎大家加移动开发技术交流群,在这里大家可以一起讨论学习,这里有大佬,也有小菜鸟,没事还能斗斗图装装逼,如果需要换工作的还能相互推荐,期待大家的加入!偷笑




猜你喜欢

转载自blog.csdn.net/u014220518/article/details/79670480