Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to run code in the UI thread calling it from the others ones

Tags:

ios

In Android there are several ways to run some code in the main thread from others ones:

 1. Activity.runOnUiThread(Runnable r)  2. new Handler.post(Runnable r);  3. View.post 

What are the analogues in iOS?

 dispatch_async(dispatch_get_main_queue(), ^{      }); 

Something else?

Thanks in advance.

like image 572
pvllnspk Avatar asked Oct 13 '12 16:10

pvllnspk


People also ask

How do I run something on the main thread?

A condensed code block is as follows: new Handler(Looper. getMainLooper()). post(new Runnable() { @Override public void run() { // things to do on the main thread } });

What is run on UI thread?

User Interface Thread or UI-Thread in Android is a Thread element responsible for updating the layout elements of the application implicitly or explicitly. This means, to update an element or change its attributes in the application layout ie the front-end of the application, one can make use of the UI-Thread.

Why should you avoid to run non UI code on the main thread?

All Android apps use a main thread to handle UI operations. Calling long-running operations from this main thread can lead to freezes and unresponsiveness. For example, if your app makes a network request from the main thread, your app's UI is frozen until it receives the network response.

Why should you avoid to run non UI code on the main thread in Android?

If you put long running work on the UI thread, you can get ANR errors. If you have multiple threads and put long running work on the non-UI threads, those non-UI threads can't inform the user of what is happening.


1 Answers

The preferred way nowadays is using GCD, with the code you quoted in your question:

dispatch_async(dispatch_get_main_queue(), ^{     // Your code to run on the main queue/thread }); 

If you prefer using a more Object-Oriented approach than GCD, you may also use an NSOperation (like an NSBlockOperation) and add it to the [NSOperationQueue mainQueue].

[[NSOperationQueue mainQueue] addOperationWithBlock:^{     // Your code to run on the main queue/thread  }]; 

This does quite the same thing as dispatch_async(dispatch_get_main_queue(), …), has the advantage of being more Objective-C/POO oriented that the plain C GCD function, but has the drawback of needing to allocate memory for creating the NSOperation objects, whereas you can avoid it using plain C and GCD.


I recommend using GCD, but there are other ways, like those two which allow you to call a selector (method) on a given object from the main thread:

  • - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait (method of NSObject so it can be called on any object)
  • Send - (void)performSelector:(SEL)aSelector target:(id)target argument:(id)anArgument order:(NSUInteger)order modes:(NSArray *)modes on the [NSRunLoop mainRunLoop]

But those solutions are not as flexible as the GCD or NSOperation ones, because they only let you call existing methods (so your object has to have a method that already exists and does what you want to perform), whereas GCD or -[NSOperationQueue addOperationWithBlock:] allows you to pass arbitrary code (using the block).

like image 157
AliSoftware Avatar answered Sep 21 '22 18:09

AliSoftware