美文网首页selector
dispatch_async(dispatch_get_main

dispatch_async(dispatch_get_main

作者: 观星 | 来源:发表于2017-06-27 10:19 被阅读1495次

    messages messages###问题

    - (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]);
        
        return YES;
    }
    
    
    2017-06-27 09:33:57.001 TestMain[1811:19444] before main queue : <NSThread: 0x60000006a080>{number = 1, name = main}
    2017-06-27 09:33:57.001 TestMain[1811:19444] after main queue : <NSThread: 0x60000006a080>{number = 1, name = main}
    2017-06-27 09:33:57.012 TestMain[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);
        
        return YES;
    }
    
    before main queue : <NSThread: 0x608000070ec0>{number = 1, name = main}
    after main queue : <NSThread: 0x608000070ec0>{number = 1, name = main}
    self.label: (null)
    main queue
    

    解决方法

    1. 参考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
    
    1. 将需要顺序的执行的代码放到同一个作用域里面

    原因

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

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

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

    相关文章

      网友评论

        本文标题:dispatch_async(dispatch_get_main

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