1.performSelector
/*Selector : 待执行的方法SEL
Object : SEL方法待传入参数
Delay : 延时时长 单位:秒 */
[self performSelector:Selector withObject:Object afterDelay:Delay];
特点:传入参数少,待延时执行的操作量很大(代码有几十行这种)。这种方式代码欣赏度高。
注: 如果传入参数太多可以使用NSInvocation将多个参数封装起来传入
2.GCD
//delayInSeconds 延时时间 单位:秒dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(<#delayInSeconds#> * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
// 延时后需要执行的方法
});
特点:1.书写简单(输入dispatch_after 回车系统就全部显示出来了。2.适用在block执行代码少于10行。太多了不如将代码封装到一个方法中。
3.NSTimer
/*TimeInterval 延时时长 单位:秒
target NSTimer注入的对象。 一般写Self
selector 延时后调用的方法
userInfo:(id)userInfo此参数可以为nil,当定时器失效时,由你指定的对象保留和释放该定时器。
repeats:(BOOL)yesOrNo当YES时,定时器会不断循环直至失效或被释放,当NO时,定时器会循环发送一次就失效。
*/
[NSTimer scheduledTimerWithTimeInterval:<#(NSTimeInterval)#> target:<#(nonnull id)#> selector:<#(nonnull SEL)#> userInfo:<#(nullable id)#> repeats:<#(BOOL)#>];
注意事项:
1.NSTimer可以精确到50-100毫秒.
2.NSTimer不是绝对准确的,而且中间耗时或阻塞错过下一个点,那么下一个点就pass过去了.
3.不用scheduled方式初始化的,需要手动addTimer:forMode: 将timer添加到一个runloop中。
而scheduled的初始化方法将以默认mode直接添加到当前的runloop中.
4.停止 - (void)invalidate;这个是唯一一个可以将计时器从runloop中移出的方法。
5.可以使用-(void)fire;方法来立即触发该定时器。在重复执行的定时器中调用此方法后立即触发该定时器,但不会中断其之前的执行计划;在不重复执行的定时器中调用此方法,立即触发后,就会使这个定时器失效。
6.定时器出错请考虑RunLoop。
6.NSTimer使用过后记得销毁
笔者建议:初学者就别碰这个NSTimer了,写着又麻烦,还容易出问题,嵌套内容还多。仅仅是为了实现功能,参考第二条GCD。
4.UIView 延时操作
/*Duration: 动画持续时长
delay : 延时多长时间执行 单位:秒
options 常规动画属性设置 UIViewAnimationOptions枚举值
animations: 延时后执行的Block代码
completion : animations Block完成操作后 执行的Block
*/
[UIView animateWithDuration:<#(NSTimeInterval)#> delay:<#(NSTimeInterval)#> options:<#(UIViewAnimationOptions)#> animations:<#^(void)animations#> completion:<#^(BOOL finished)completion#>]
特点:这个方法一般配合UI的基础属性改变,为产生渐变效果。比如:frame 、alpha、center等等。 但也是进行延时执行的任务。 而且还有一个好处是:在完成某件事情后也有回调。这样就可以处理多个过程的逻辑。
5.CADisplayLink
self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateTextColor)];
self.displayLink.paused = YES;
[self.displayLink addToRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
-(void)updateTextColor{}
- (void)startAnimation{
self.beginTime = CACurrentMediaTime();
self.displayLink.paused = NO;
}
- (void)stopAnimation{
self.displayLink.paused = YES;
[self.displayLink invalidate];
self.displayLink = nil;
}
特点:
1.使用场合相对专一,适合做UI的不停重绘
2.在添加进runloop的时候我们应该选用高一些的优先级,来保证动画的平滑.
3.通过pause属性开控制CADisplayLink的运行。
4.结束一个CADisplayLink的时候,应该调用-(void)invalidate
5.CADisplayLink在正常情况下会在每次刷新结束都被调用,比NSTimer精确度高非常多。