Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to determine what's running on main thread + slowing down UI?

I put in a new data loading feature in my app. It's meant to transfer and process the contents of a large database from the mobile device into the backend. In ever function I run in this pipeline, the entire contents of the function are inside a

dispatch_async

This dispatches to a non-main thread. I have also verified with logs that these are working. Every function along the pipeline is off the main thread. And yet I am experiencing UI freeze-up.

Questions:

  1. What's the best way to figure out what is on the main thread and what it's doing/waiting for?
  2. Is it ever possible to have non-main threads doing so much it actually impacts the main thread?
like image 958
helloB Avatar asked Aug 09 '16 20:08

helloB


People also ask

How do you check if code is running on main thread?

if(Looper. getMainLooper(). getThread() == Thread. currentThread()) { // Current Thread is Main Thread. }

Is the main thread the same as the UI thread?

As such, the main thread is also sometimes called the UI thread. However, under special circumstances, an app's main thread might not be its UI thread; for more information, see Thread annotations. The system does not create a separate thread for each instance of a component.

Which thread is responsible for updating the UI?

Only the Main thread, also known as the UI thread can update the UI a.f.a.i.k.

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

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

You should profile your app with Instruments. Time Profiler (make sure to use "Record Waiting Threads" option) can be useful, as is System Trace. For both, you might want to use the "Thread Strategy" view, enter image description here, focusing on the main thread. There are a bunch of WWDC videos that describe various approaches, including the dated, yet still relevant, 2012 video Building Concurrent User Interfaces on iOS. Also look for newer WWDC videos that reference "profiling" and "instruments".

Regarding non-main threads adversely affecting performance, it's generally negligible and you probably have something else going on. The only time it's a significant problem is when you're using a very old device that doesn't support multithreading.

By the way, are you 100% sure the main thread is really not being responsive? Or is it possibly that you're just not seeing UI updates being reflected in a timely manner? This can be a result of accidentally doing UI updates from the background thread rather than dispatching them back to the main queue.

If you want more concrete counsel, we need a reproducible example of the performance problem. But in the abstract,

  • make sure you don't have any time consuming operations on the main queue;
  • make sure all UI updates are dispatched back to the main queue ... this includes anything that might trigger the update of a UIKit control;
  • make sure your code doesn't "wait" for anything from the main thread (e.g. waiting for a semaphore, waiting for operations on an operation queue, waiting for dispatch group, etc.); and
  • remember that not all asynchronous API will call their completion handlers on background queues (in fact, many dispatch it back to the main queue for the sake of ease of use), so if you're doing anything time consuming in a completion handler, confirm that it's actually getting run on a background thread or not.
like image 151
Rob Avatar answered Nov 14 '22 22:11

Rob