Each thread has its own stack — what about the heap?
Answer
The stack is per thread: it is created together with the thread (the main one is 1 MB on iOS, background Thread and GCD threads get 512 KB by default; the size can be set via Thread.stackSize) and destroyed with it. A function's frame is visible only to the thread that called it, so locals are thread-safe "by construction".
The heap is one per process, shared by all threads. Any object two threads can reach through a reference is shared state: reads and writes must be synchronized (actor, Mutex/OSAllocatedUnfairLock, a serial queue), otherwise you have a data race.
The rest of this answer, with code and interview follow-ups, is in the DevPrep app.
Read the full answer in DevPrep