Race conditions take many forms. One that is likely familiar to everyone can be encountered in multithreading applications. Yet there is another one, one that is as common but well disguised: reentrancy.
While possibility of race conditions in the multithreaded code is a side effect of the desired behavior when multiple processing units compute result based on the shared data, Same-Stack Race Conditions are outright incorrect.
KVO, while often a hated victim, is not the only troubled technology. Everything that uses same-stack callbacks, including Delegates and Notifications, is susceptible. Although with latter it’s easier to write code that is mostly correct for common cases.
However, when working with the UI, callbacks are often desirable because the whole change must be delivered within the same iteration of the run loop: you likely want the visuals to be updated atomically, within the same frame.
Unfortunately this topic is seldom promoted by the programming guides, less so encountered in practice. I advise you to develop your applications, especially those built on top of run loops and same-stack events, defensively.
In Objective-C and Cocoa I use the following lock-like approach that relies on RAII scopes (and relatively “modern” Clang and GCC that support the
cleanup attribute) to detect the errors: