“This is the 26th day of my participation in the November Gwen Challenge. See details of the event: The Last Gwen Challenge 2021”.
- Ensuring thread-safety on a framework as large as UIKit is a major task with significant costs. UIKit is not thread-safe. For example, if you traverse a subView in one thread and delete that subView in another thread, there will be a problem
- In fact, if you want to update another UI in a child thread, you have to wait until the child thread finishes running. When the child thread terminates, it returns to the main thread.
- UI update cannot be done in the child thread, we see UI update is actually the child thread code completed, and automatically entered the main thread, the implementation of the child thread UI update stack, this intermediate time is very short, let everyone mistakenly think that the thread can update the UI. If the child thread is always running, the function stack main thread for UI updates in the child thread is not known, that is, cannot be updated. Only a very small number of UIs can be updated directly, because the current environment is retrieved when a thread is opened. For example, when a button is clicked, the button responds by opening a child thread that updates the UI in a timely manner.
First, for security reasons
Because THE UIKit framework is not thread-safe, when multiple threads operate on the UI at the same time, resources can be grabbed, resulting in crashes, UI exceptions and other issues. If the same background image is set in two threads, it is very likely that the background image will be released twice, causing the program to crash. Or if one thread traverses for a subView and deletes the subView in another thread, it will cause confusion. Apple has made most drawing methods and classes such as UIColor thread-safe, but still recommends keeping UI operations in the main thread. For example, we need to read an image object in the child thread, using the interface [UIImage imageNamed:], but imageNamed: is actually thread-safe after iOS9, which is the main thread before iOS9. So, we need to switch from the child thread to the main thread to get the image, and then cut back to the child thread to get the image, so we have to use sync.
Second, out of user experience
In iOS, only the main thread can refresh the UI immediately. You can’t update the UI in the child thread, and the reason we see that the child thread can update the UI is that when the child thread finishes executing, it automatically enters the main thread to execute the code that updated the UI in the child thread. Since the child thread execution time is very short, we mistakenly believe that the child thread can update the UI. If the child thread is always running, the UI cannot be updated because there is no way to enter the main thread. The main thread is used to display \ refresh the UI interface and handle UI events (such as click events, scroll events, drag events, etc.). Time-consuming operations will block the main thread, seriously affecting UI smoothness and giving users a bad “stuck” experience. Therefore, the solution is to asynchronously start a sliver thread and let time-consuming operations complete in the child thread without affecting the main thread’s tasks. When the task in the child thread is complete, go back to the main thread to refresh the UI and display the UI.
3. The program enters the main thread as soon as it starts running
In child thread, if you want to update the UI, only two kinds of practice: method 1: wait until the end of the thread to run, the child thread after the end of the new UI system automatically return to the main practice 2: don’t have to wait until the end of the thread to run, we directly outside of the UI code + the home side column, write the GCD asynchronous function can realize the main thread immediately update the UI