美文网首页
dispatch_async(dispatch_get_main

dispatch_async(dispatch_get_main

作者: lucifer_1911 | 来源:发表于2019-10-09 13:48 被阅读0次

    dispatch_async(dispatch_get_main_queue(),^{})存在的一个坑

    0.1642017.06.27 10:19:33字数 228阅读 3444

    -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{// Override point for customization after application launch.NSLog(@"before main queue : %@",[NSThread currentThread]);dispatch_async(dispatch_get_main_queue(),^{NSLog(@"main queue");});NSLog(@"after main queue : %@",[NSThread currentThread]);returnYES;}2017-06-2709:33:57.001TestMain[1811:19444]before main queue:<NSThread:0x60000006a080>{number=1,name=main}2017-06-2709:33:57.001TestMain[1811:19444]after main queue:<NSThread:0x60000006a080>{number=1,name=main}2017-06-2709:33:57.012TestMain[1811:19444]main queue

    可以看到在main thread中,执行顺序并不是和代码顺序一样,

    dispatch_async(dispatch_get_main_queue(),^{NSLog(@"main queue");});

    最后执行。

    如果不注意的话,可能会导致一些问题。

    -(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{// Override point for customization after application launch.NSLog(@"before main queue : %@",[NSThread currentThread]);dispatch_async(dispatch_get_main_queue(),^{NSLog(@"main queue");self.label=[UILabel new];});NSLog(@"after main queue : %@",[NSThread currentThread]);NSLog(@"self.label: %@",self.label);returnYES;}before main queue:<NSThread:0x608000070ec0>{number=1,name=main}after main queue:<NSThread:0x608000070ec0>{number=1,name=main}self.label:(null)main queue

    解决方法

    参考SDWebImage的宏定义,判断一下当前是不是主线程,如果是直接执行,如果不是,异步执行

    #ifndef dispatch_main_async_safe    #define dispatch_main_async_safe(block)\    if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {\    block();\    } else {\    dispatch_async(dispatch_get_main_queue(), block);\    }    #endif

    将需要顺序的执行的代码放到同一个作用域里面

    原因

    应该是和runloop有关的,但是具体的解释还没想明白。

    dispatch_async(dispatch_get_main_queue(),^{NSLog(@"main queue");self.label=[UILabel new];});

    dispatch_async将block提交给了queue然后立即返回,但是block什么时候执行,由queue说了算。然后,就不知道了……

    更新

    block 什么时候执行由Runloop说了算,不是由queue说了算,实际就是下一个runloop循环会执行,因为runloop在唤醒后会去处理相关的任务

    调用信息

    void_dispatch_main_queue_callback_4CF(void*ignored DISPATCH_UNUSED){// the main queue cannot be suspended and no-one looks at this bit// so abuse it to avoid dirtying more memoryif(_dispatch_main_q.dq_side_suspend_cnt){return;}_dispatch_main_q.dq_side_suspend_cnt=true;_dispatch_main_queue_drain(&_dispatch_main_q);_dispatch_main_q.dq_side_suspend_cnt=false;}

    相关文章

      网友评论

          本文标题:dispatch_async(dispatch_get_main

          本文链接:https://www.haomeiwen.com/subject/rlfgpctx.html