ios中几种延时处理

版本记录

版本号 时间
V1.0 2017.05.01

前言

很多时候我们需要进行延迟处理,在ios中延迟方法有很多,下面就介绍几种主要的延时方法,各有优缺点,希望大家能比较使用。

详情

一、perform selector方法

ios中关于这个方法有几个方法,主要如下:

@interface NSObject (NSDelayedPerforming)

- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(nullable id)anArgument afterDelay:(NSTimeInterval)delay;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget selector:(SEL)aSelector object:(nullable id)anArgument;
+ (void)cancelPreviousPerformRequestsWithTarget:(id)aTarget;

@end

这个方法有个优点就是不会阻塞线程。此方式要求必须在主线程中执行,否则无效,没有取消的方法。我们就以第二个方法进行举例吧。

1. JJDelayMethodVC.m

#import "JJDelayMethodVC.h"

@interface JJDelayMethodVC ()

@end

@implementation JJDelayMethodVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //第一种延时函数
    [self delayMethodOne];

}

#pragma mark - Object Private Function

- (void)delayMethodOne
{
    NSDate *dateBefore = [NSDate date];
    NSLog(@"dateBefore---%@",dateBefore);
    [self performSelector:@selector(delayMethodOneAction) withObject:nil afterDelay:2];

}

#pragma mark - Action

- (void)delayMethodOneAction
{
    NSDate *dateAfter = [NSDate date];
    NSLog(@"dateAfter---%@",dateAfter);

}

@end

我们看输出。

2017-05-01 22:35:37.231 delayMethod[6783:293524] dateBefore---2017-05-01 14:35:37 +0000
2017-05-01 22:35:39.302 delayMethod[6783:293524] dateAfter---2017-05-01 14:35:39 +0000

可以看见确实延时了2s。上面这个方法的object可以传参,然后在执行selector的方法中进行接收并处理。


二、GCD dispatch_after方法

GCD中dispatch_after方法也可以实现延迟。而且不会阻塞线程,效率较高(推荐使用),并且可以在参数中选择执行的线程,同样没有可取消的方法。

#import "JJDelayMethodVC.h"

@interface JJDelayMethodVC ()

@end

@implementation JJDelayMethodVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //第一种延时函数
//    [self delayMethodOne];
    
    //第二种延时函数 GCD dispatch
    [self delayByDispatch];

}

#pragma mark - Object Private Function

- (void)delayByDispatch
{
    NSDate *dateBefore = [NSDate date];
    NSLog(@"dateBefore---%@",dateBefore);
    
    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC));
    dispatch_after(time, dispatch_get_main_queue(), ^{
        
        NSDate *dateAfter = [NSDate date];
        NSLog(@"dateAfter---%@",dateAfter);
    });

}

@end

我们看输出结果。

2017-05-01 22:53:14.991 delayMethod[6980:303434] dateBefore---2017-05-01 14:53:14 +0000
2017-05-01 22:53:17.992 delayMethod[6980:303434] dateAfter---2017-05-01 14:53:17 +0000

三、UIView动画实现延时

  我们都知道UIView可以实现动画延迟,延时操作写在block里面,这里需要说明的是,block中的代码对于是支持animation的代码,才会有延迟效果,对于不支持animation的代码不会有延迟效果。

下面我们看代码。

#import "JJDelayMethodVC.h"

@interface JJDelayMethodVC ()

@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation JJDelayMethodVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
    titleLabel.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:titleLabel];
    self.titleLabel = titleLabel;
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //第一种延时函数
//    [self delayMethodOne];
    
    //第二种延时函数 GCD dispatch
//    [self delayByDispatch];
    
    //UIView实现延迟
    [self delayByAnimation];

}

#pragma mark - Object Private Function

- (void)delayByAnimation
{
    NSDate *dateBefore = [NSDate date];
    NSLog(@"dateBefore---%@",dateBefore);

    [UIView animateKeyframesWithDuration:0.25 delay:5 options:UIViewKeyframeAnimationOptionLayoutSubviews animations:^{
        self.titleLabel.transform = CGAffineTransformMakeTranslation(0, 300);
    } completion:^(BOOL finished) {
        NSDate *dateAfter = [NSDate date];
        NSLog(@"dateAfter---%@",dateAfter);

        self.titleLabel.transform = CGAffineTransformIdentity;
    }];

}

@end


然后我们看输出和gif图。

2017-05-01 23:08:39.491 delayMethod[7238:313886] dateBefore---2017-05-01 15:08:39 +0000
2017-05-01 23:08:44.816 delayMethod[7238:313886] dateAfter---2017-05-01 15:08:44 +0000

ios中几种延时处理_第1张图片
动画延时

  需要说明的是,UIview动画延迟是不会阻塞线程的。


四、NSThread sleep方法

  这个方法也可以实现延时,其实就是让该线程睡眠一段时间,所以它一定会阻塞线程,浪费资源,所以一般是不推荐使用的。它没有取消的方法,可以放在主线程或者子线程中,如果一定要用还是建议放在子线程中防止卡顿界面。

#import "JJDelayMethodVC.h"

@interface JJDelayMethodVC ()

@property (nonatomic, strong) UILabel *titleLabel;


@end

@implementation JJDelayMethodVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
    titleLabel.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:titleLabel];
    self.titleLabel = titleLabel;
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //第一种延时函数
//    [self delayMethodOne];
    
    //第二种延时函数 GCD dispatch
//    [self delayByDispatch];
    
    //UIView实现延迟
//    [self delayByAnimation];
    
    //第四种  thread sleep方法
    [self delayByThreadSleep];

}

#pragma mark - Object Private Function

- (void)delayByThreadSleep
{
    
    NSLog(@"%@",[NSThread currentThread]);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSDate *dateBefore = [NSDate date];
        NSLog(@"dateBefore---%@",dateBefore);
        
        [NSThread sleepForTimeInterval:3];
        
        NSDate *dateAfter = [NSDate date];
        NSLog(@"dateAfter---%@",dateAfter);
        
        NSLog(@"%@",[NSThread currentThread]);
        
    });

}

@end

看输出结果。

2017-05-01 23:44:20.307 delayMethod[7589:330545] {number = 1, name = main}
2017-05-01 23:44:20.356 delayMethod[7589:330647] dateBefore---2017-05-01 15:44:20 +0000
2017-05-01 23:44:23.432 delayMethod[7589:330647] dateAfter---2017-05-01 15:44:23 +0000
2017-05-01 23:44:23.432 delayMethod[7589:330647] {number = 3, name = (null)}

五、NSTime 定时器方法

  定时器NSTimer也可以实现延迟,是一种非阻塞的执行方式。取消的话可以先判断isInvalidate然后调用invalidate取消该定时器。

我们先看代码。

#import "JJDelayMethodVC.h"

@interface JJDelayMethodVC ()

@property (nonatomic, strong) UILabel *titleLabel;

@end

@implementation JJDelayMethodVC

#pragma mark - Override Base Function

- (void)viewDidLoad
{
    [super viewDidLoad];

    UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 100)];
    titleLabel.backgroundColor = [UIColor orangeColor];
    [self.view addSubview:titleLabel];
    self.titleLabel = titleLabel;
    
    self.view.backgroundColor = [UIColor lightGrayColor];
    
    //第一种延时函数
//    [self delayMethodOne];
    
    //第二种延时函数 GCD dispatch
//    [self delayByDispatch];
    
    //UIView实现延迟
//    [self delayByAnimation];
    
    //第四种  thread sleep方法
//    [self delayByThreadSleep];
    
    //第五种 timer方法
    [self delayByTimer];

}

#pragma mark - Object Private Function

- (void)delayByTimer
{
    
    NSDate *dateBefore = [NSDate date];
    NSLog(@"dateBefore---%@",dateBefore);
    
    NSLog(@"%@",[NSThread currentThread]);

    NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(delayByTimerAction) userInfo:nil repeats:NO];
}

- (void)delayByTimerAction
{
    NSDate *dateAfter = [NSDate date];
    NSLog(@"dateAfter---%@",dateAfter);
    
    NSLog(@"%@",[NSThread currentThread]);
}

@end

然后我们看输出结果。

2017-05-01 23:53:38.677 delayMethod[7704:335921] dateBefore---2017-05-01 15:53:38 +0000
2017-05-01 23:53:38.677 delayMethod[7704:335921] {number = 1, name = main}
2017-05-01 23:53:41.752 delayMethod[7704:335921] dateAfter---2017-05-01 15:53:41 +0000
2017-05-01 23:53:41.753 delayMethod[7704:335921] {number = 1, name = main}

我这里没有取消timer,大家可以自己加上。

后记

  时间就这么多了,先写这么多吧,以后有更好的东西在和大家分享。谢谢大家,晚安。

ios中几种延时处理_第2张图片
送给最喜欢向日葵的你吧!

你可能感兴趣的:(ios中几种延时处理)