iOS 在主线程操作UI不能保证安全

2018-10-15  本文已影响0人  Pandakingli

先看一下SDWebImage的一段代码

#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

是不是很奇怪,一般来说下面的代码就足够了啊,可以保证在主线程运行

if ([NSThread isMainThread]) {
       block();
} else {
   dispatch_async(dispatch_get_main_queue(), ^{
       block();
   })
}

github issues上看到下面的讨论:


24025596: MapKit: It's not safe to call MKMapView's addOverlay on a non-main-queue, even if it is executed on the main thread #7053

在非主队列中调用MKMapView的 addOverlay方法是不安全的,即使是在主线程,也有可能造成崩溃。

@NachoSoto I contacted Apple DTS, they confirmed it is a bug in MapKit. But they also cautioned that the pattern of dispatch_sync and the isMainThread will likely run into more issues like this and the one reported by @laptobbe above.

They also explicitly stated that main queue and the main thread are not the same thing, but are have subtle differences, as shown in my demo app.

UI 主线程执行不一定安全.png

在主队列中的任务,一定会放到主线程执行
所以只要是在主队列中的任务,既可以保证在主队列,也可以保证在主线程中执行。所以就可以通过判断当前队列是不是主队列来代替判断当前执行任务的线程是否是主线程,这样会更加安全。

上一篇下一篇

猜你喜欢

热点阅读