The main thread checker is a godsend. Enabling it + TSAN + Core Data concurrency assertions have reduced the threading bugs my team deals with to almost 0.
Anywhere we're doing something specific, we make liberal use of `dispatchPrecondition(condition: .onQueue(mySerialQueue))` or `assert(Thread.isMainThread)`.
Even in places where we are doing multithreaded UI rendering (mostly CATiledLayer), it's become a non-issue. It's a night-and-day difference compared to 5+ years ago.
This basically just boils down to "don't touch the UI off the main thread". There are some exceptions with CoreAnimation, but other than that the main thread checker will yell at you if you do something wrong.