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上看到下面的讨论:
在非主队列中调用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在主队列中的任务,一定会放到主线程执行
所以只要是在主队列中的任务,既可以保证在主队列,也可以保证在主线程中执行。所以就可以通过判断当前队列是不是主队列来代替判断当前执行任务的线程是否是主线程,这样会更加安全。