Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why must UIKit operations be performed on the main thread?

I am trying to understand why UI operations can't be performed using multiple threads. Is this also a requirement in other frameworks like OpenGL or cocos2d?

How about other languages like C# and javascript? I tried looking in google but people mention something about POSIX threads which I don't understand.

like image 215
Kunal Balani Avatar asked Aug 27 '13 13:08

Kunal Balani


People also ask

Why we should update UI on main thread?

In all cases, your app should only update UI objects on the main thread. This means that you should craft a negotiation policy that allows multiple threads to communicate work back to the main thread, which tasks the topmost activity or fragment with the work of updating the actual UI object.

Why is UIKit not thread safe?

As we can see, most of the components in UIKit is described as nonatomic `, this means there are not thread safe. And it is unrealistic to design all the properties as thread-safe in UIKit because it is such a huge framework.

Why is the main thread sometimes also called UI thread?

This thread is in charge of the user interface. Every additional component is also run on this thread, unless explicitly instructed otherwise. It is also the only thread that may update the user interface. For this reason, it's also often referred to as a UI thread.

What is main thread in IOS?

A thread is a sequence of instructions that can be executed by a runtime. Each process has at least one thread. In iOS, the primary thread on which the process is started is commonly referred to as the main thread. This is the thread in which all UI elements are created and managed.


3 Answers

In Cocoa Touch, the UIApplication i.e. the instance of your application is attached to the main thread because this thread is created by UIApplicatioMain(), the entry point function of Cocoa Touch. It sets up main event loop, including the application’s run loop, and begins processing events. Application's main event loop receives all the UI events i.e. touch, gestures etc.

From docs UIApplicationMain(),

This function instantiates the application object from the principal class and instantiates the delegate (if any) from the given class and sets the delegate for the application. It also sets up the main event loop, including the application’s run loop, and begins processing events. If the application’s Info.plist file specifies a main nib file to be loaded, by including the NSMainNibFile key and a valid nib file name for the value, this function loads that nib file.

These application UI events are further forwarded to UIResponder's following the chain of responders usually like UIApplication->UIWindow->UIViewController->UIView->subviews(UIButton,etc.)

Responders handle events like button press, tap, pinch zoom, swipe etc. which get translated as change in the UI. Hence as you can see these chain of events occur on main thread which is why UIKit, the framework which contains the responders should operate on main thread.

From docs again UIKit,

For the most part, UIKit classes should be used only from an application’s main thread. This is particularly true for classes derived from UIResponder or that involve manipulating your application’s user interface in any way.

EDIT

Why drawRect needs to be on main thread?

drawRect: is called by UIKit as part of UIView's lifecycle. So drawRect: is bound to main thread. Drawing in this way is expensive because it is done using the CPU on the main thread. The hardware accelerate graphics is provided by using the CALayer technique (Core Animation).

CALayer on the other hand acts as a backing store for the view. The view will then just display cached bitmap of its current state. Any change to the view properties will result in changes in the backing store which get performed by GPU on the backed copy. However, the view still needs to provide the initial content and periodically update view. I have not really worked on OpenGL but I think it also uses layers(I could be wrong).

I have tried to answer this to the best of my knowledge. Hope that helps!

like image 115
Amar Avatar answered Oct 17 '22 04:10

Amar


from : https://www.objc.io/issues/2-concurrency/thread-safe-class-design/

It’s a conscious design decision from Apple’s side to not have UIKit be thread-safe. Making it thread-safe wouldn’t buy you much in terms of performance; it would in fact make many things slower. And the fact that UIKit is tied to the main thread makes it very easy to write concurrent programs and use UIKit. All you have to do is make sure that calls into UIKit are always made on the main thread.

So according to this the fact that UIKit objects must be accessed on the main thread is a design decision by apple to favor performance.

like image 36
Andrespch Avatar answered Oct 17 '22 04:10

Andrespch


C# behaves the same (see eg here: Keep the UI thread responsive). UI updates have to be done in the UI thread - most other things should be done in the background hen possible.

If that wouldn't be the case there would probably be a synchronization hell between all updates that have to be done in the UI ...

like image 1
TheEye Avatar answered Oct 17 '22 04:10

TheEye