app modifying the autolayout engine from a background thread

1.8k views Asked by At

I am almost done migrating an iOS app of mine to Swift 3.0. But I still have a few cases similar to the one below. Most of them I have been able to solve by putting the problematic code on the main thread.

In some other cases, I can't figure out, which part of my code is executing on the wrong thread. And I get a message like this one:

This application is modifying the autolayout engine from a background thread after the engine was accessed from the main thread. This can lead to engine corruption and weird crashes.
 Stack:(
    0   CoreFoundation                      0x000000018765a1d8 <redacted> + 148
    1   libobjc.A.dylib                     0x000000018609455c objc_exception_throw + 56
    2   CoreFoundation                      0x000000018765a108 <redacted> + 0
    3   Foundation                          0x0000000188241ea4 <redacted> + 192
    ....................
    16  libsystem_pthread.dylib             0x00000001866eece4 <redacted> + 200
    17  libsystem_pthread.dylib             0x00000001866ee378 pthread_mutex_lock + 0
    18  libsystem_pthread.dylib             0x00000001866edda4 start_wqthread + 4
)

Is there some special technic (option when using the debugger or ??) I can use to trace the path followed by the progran, to see where this is happening?

2

There are 2 answers

3
Gurdev Singh On BEST ANSWER

I don't think there is any other inbuilt tool for debugging such crashes because it's the code which is modifying the AutoLayout UI elements/constraints from the code which is either running in Background thread or completion handlers. All completion handlers by default run in background thread. You need to use the GCD to update the UI elements from your completion handler blocks.

0
Ashish P On

Obviously you are doing some UI update on back ground thread. Cant predict exactly where, without seeing your code.

These are some situations it might happen:-

  1. you might be doing something on background thread and not using. Being in the same function this code is easier to spot.

    DispatchQueue.main.async { // do UI update here }
    
  2. calling a func doing web request call on background thread and its completion handler calling other func doing ui update.

to solve this try checking code where you have updated the UI after webrequest call.

 // Do something on background thread
DispatchQueue.global(qos: .userInitiated).async {
   // update UI on main thread
   DispatchQueue.main.async {
                // Updating whole table view
                self.myTableview.reloadData()
            }
}