dispatch_queue_async_safe 与 disp

2021-02-22  本文已影响0人  镜像
#ifndef dispatch_queue_async_safe
#define dispatch_queue_async_safe(queue, block)\
    if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(queue)) {\
        block();\
    } else {\
        dispatch_async(queue, block);\
    }
#endif

#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block) dispatch_queue_async_safe(dispatch_get_main_queue(), block)
#endif

不是所有在主线程执行的任务,都是主队列的任务,但是主队列的任务,一定在主线程执行
如果在主线程内调用dispatch_async(dispatch_get_main_queue(), block),可能会导致block在下一次runloop执行,从而导致更新UI时出错,而且还浪费资源

- (void)viewDidLoad
{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self asdasd];
    });
    
    dispatch_queue_t queue = dispatch_queue_create("asd", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        [self asdasdasd];
    });
    
    dispatch_main_async_safe(^{
        NSLog(@"666666");
    });
    
    NSLog(@"555555");
}

- (void)asdasd
{
    dispatch_main_async_safe(^{
        NSLog(@"111111");
    });
    NSLog(@"222222");
}

- (void)asdasdasd
{
    dispatch_main_async_safe(^{
        NSLog(@"3333333");
    });
    NSLog(@"444444");
}

输出顺序:

Controller.m:70 666666
Controller.m:69 555555
Controller.m:116    444444
Controller.m:106    111111
Controller.m:108    222222
Controller.m:114    3333333

这段代码个人理解就是block中执行的代码,如果在所在队列,则直接执行block中代码,否则在下一次runloop中执行。
使用dispatch_main_async_safe保证block中的代码在主线程执行。

上一篇下一篇

猜你喜欢

热点阅读