When we first started learning iOS, we were told that UI operations must be performed on the main thread. This is because UIKit methods are not thread-safe, and ensuring thread safety requires a lot of overhead. So the question is, is it safe to perform UI operations in the main thread? Obviously, the answer is no! In Apple's MapKit framework, there is a method called addOverlay, which requires the code to be executed not only on the main thread but also on the main queue of GCD when it is implemented at the bottom layer. This is an extremely rare problem, but someone has already encountered this problem when using ReactiveCocoa and submitted an issue. Apple's Developer Technology Support admitted that this is a bug. Regardless of whether this is a bug or a legacy design, or whether it is just a quibble, in order to avoid falling into the same trap again, I think it is necessary to analyze the cause of the problem and the solution. GCD knowledge review In GCD, the main queue can be obtained by using the dispatch_get_main_queue() function. Calling the dispatch_sync() method will synchronously submit the task to the specified queue. Note the difference between queues and threads. There is no "ownership relationship" between them. When we submit a task synchronously, we first block the current queue, and then wait until the next runloop to execute the block in the appropriate thread. Before executing a block, it will first look for a suitable thread to execute the block, and then block the thread until the block is executed. The rule for finding threads is: any block submitted to the main queue will be executed in the main thread. Under the premise of not violating this rule, the document also tells us that the system will automatically optimize and execute the block in the current thread as much as possible. By the way, the sufficient condition for GCD deadlock is: "repeatedly submitting blocks to the current queue synchronously". In principle, the cause of the deadlock is that the submitted block blocks the queue, and after the queue is blocked, dispatch_sync() can never be completed. It can be seen that this has nothing to do with the thread where the code is located. Another example can also prove this point. In the main thread, a block is synchronously dispatched to a serial queue. According to the principle of thread selection above, the block will be executed in the main thread, but it will not cause deadlock:
Cause Analysis After all this talk, let's get back to the bug described earlier. Now we know that even if the code is executed in the main thread, it is likely not running in the main queue (and vice versa). If we call MapKit's addOverlay method in a subqueue, even if it is currently in the main thread, it will cause a bug because the underlying implementation of this method determines the main queue rather than the main thread. Thinking further, sometimes in order to ensure that UI operations run on the main thread, if there is a function that can be used to create a new UILabel, in order to ensure thread safety, the code may be like this:
Strictly speaking, this way of writing is not 100% safe, because we cannot know whether the relevant system methods have the above bugs. Solution Since the block submitted to the main queue must be run in the main thread, and thread switching in GCD is usually caused by specifying a queue, we can make a more rigorous judgment, that is, to judge whether it is in the main queue instead of whether it is in the main thread. GCD does not provide an API to make corresponding judgments, but we can find another way to use the dispatch_queue_set_specific and dispatch_get_specific methods to mark the main queue:
Use the isMainQueue method instead of [NSThread isMainThread] to get better safety. References 1.Community bug reports about MapKit http://t.cn/RtxivSc 2.GCD's Main Queue vs Main Thread http://t.cn/RthOawx 3. Similar pitfalls encountered in ReactiveCocoa http://t.cn/RtxJFRX 4.Why can't we use a dispatch_sync on the current queue? http://t.cn/RtxJgPi |
<<: RecyclerView implements sliding deletion and dragging functions
>>: Android Studio template file group
Come and check out the latest TikTok Ads product ...
"I hope my son will become a dragon and my da...
Why do I always want to stick close to others? So...
Douyin became a huge hit like a bolt from the blu...
Today is the Lesser Heat. Although it is not the ...
Brand promotion is not just a high-sounding conce...
As an APP operator, you often need to plan activi...
At present, more and more people are starting to ...
Review expert: Wang Xuejiang, professor at Capita...
[[164788]] This post was contributed by Eugene Tr...
What exactly is the "Double Holiday" an...
The Harvard Business Review once pointed out: In ...
In the future, life will become more and more dif...
Today, the fragmented society has led to a sharp ...
Source: NetEase Technology Original title: "...