前言
在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方法。
结束语
欢迎各位大神补充!
欢迎大家加移动开发技术交流群,在这里大家可以一起讨论学习,这里有大佬,也有小菜鸟,没事还能斗斗图装装逼,如果需要换工作的还能相互推荐,期待大家的加入!