In some libraries, we can find a macro define like dispatch_main_async_safe
, such as SDWebImage. There is the code:
#ifndef dispatch_main_async_safe
#define dispatch_main_async_safe(block)\
if (dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL) == dispatch_queue_get_label(dispatch_get_main_queue())) {\
block();\
} else {\
dispatch_async(dispatch_get_main_queue(), block);\
}
#endif
I am very confused why this macro define is necessary, and what will happen if we use function dispatch_async
directly. If using dispatch_async
directly would lead some bugs or crashes, please give an example.
Any ideas will be appreciated, thanks.
This post should help: http://blog.benjamin-encz.de/post/main-queue-vs-main-thread/.
I think using dispatch_async
directly will not lead to crashes.
Imagining the scenario where you will update UI after fetching the data from network, you might need to check if the current queue is main queue, the use of macro dispatch_main_async_safe
provides convenience for dispatching tasks on main queue and ensures the next tasks to be always executed on main queue. The first step of the above code is to determine if the current queue is main queue, main queue must mean it is in a main thread, if the result is yes, executing the block immediately. you might not need to have to dispatch the next task to the main queue asynchronously.
Otherwise, you must dispatch the next task to the main queue asynchronously.
As the above post mentioned, the main thread can have multiple queues running in it. We should ensure the UI related task to be always executed on main queue.
I hope this could help you.