I still find it hard to write maintainable multi-threaded code for macOS or iOS [...] without having to worry about the minutiae of parallelism (threads, semaphores, locks, barriers, etc.). I find this surprising, as GCD does insulate you from that low-level stuff. When you need to work with mutable data, just create a dispatch queue, and only ever access the data by dispatching a function to the queue. Both Swift an…
GCD is super great and I use it a lot (...if you had to extend AsyncTask recently: my condolences), but it doesn't safeguard you from race conditions, dealing with locks and all that fun stuff.