iOS延时执行测试

#import "Person.h"

@implementation Person

- (void)testLog {
    [self performSelector:@selector(logd) withObject:nil afterDelay:0];//1
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        NSLog(@"c");
    });//2
    
    [self performSelector:@selector(logb)];//3
    
    NSLog(@"a");//4
}

- (void)logd {
    NSLog(@"d");
}

- (void)logb {
    NSLog(@"b");
}

@end

上面这段代码在OS命令行程序和iOS程序中运行结果完全不同
这是在OS命令行程序中结果
这是在iOS程序中运行结果

在iOS程序中运行结果的原理

  • performSelector:@selector(logb)
    知识点:告诉线程直接调用方法
  • -(void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
    知识点:这个方法是单线程的,也就是说只有当前调用此方法的函数执行完毕后,selector方法才会被调用。
  • dispatch_after能让我们添加进队列的任务延时执行,该函数并不是在指定时间后执行处理,而只是在指定时间追加处理到dispatch_queue

程序执行到//1的时候,系统会等待testlog全部执行完再延时0s执行logd方法;
执行到//2的时候,告诉主队列0s后添加logc任务到主队列;
执行到//3的时候,主线程直接执行logb方法,打印b;
执行到//4的时候,主线程直接打印a;
打印完a,将需要延时加入进队列的方法加进主队列,而(void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay需要等待当前函数testlog执行完才能调用,所以先加进队列的是logc,打印c;
打印完c,testlog函数全部执行完毕,执行logd方法,打印d。

如有错误,敬请指出。

你可能感兴趣的:(iOS延时执行测试)