#inadvertently
I made a topical cartoon.

I made a topical cartoon.


Credit: Jeffmock CC-BY-SA-3.0
On this 15th anniversary of 9/11, I recall my most vivid memory of the events. I drove in to work at Honeywell Aerospace in Kansas City after watching the second aircraft crash into the Twin Towers on live TV. Partway through my drive, I saw something I’d never seen before or since: arcing contrails, all over the clear blue Kansas sky. It wasn’t after I got in to work that I found out that the FAA had grounded all aircraft in flight. Those contrails showed where aircraft turned around and landed where they came from.
We didn’t get much work done that day. Someone hooked up large screen TVs and we watched as the towers fell.

This is the sixth and final post in a series about Grand Central Dispatch.
Long time users of GCD will tell you: it’s easy to forget where you are. Which queue am I on? Should I dispatch_sync to a queue that protects my variables, or has my caller taken care of that?
In this post I will describe a simple naming convention that has kept me sane over the years. Follow it, and you shouldn’t ever deadlock or forget to synchronize access to your member variables again.
When designing thread-safe code, it helps to have a library mindset. You should distinguish between the external or public interface (API), and the internal or private interface. The public API is presented in public headers, and the private interface is presented in private headers, used only by the library’s developers.
The ideal thread-safe public API does not expose threading or queueing at all (unless, of course, thread or queue management is the point of your library’s utility). It should simply not be possible to induce a race condition or deadlock when using your library. Let’s take a look at this classic example:
// Public header
#import <Foundation/Foundation.h>
// Thread-safe
@interface Account: NSObject
@property (nonatomic, readonly, getter=isClosed) BOOL closed;
@property (nonatomic, readonly) double balance;
- (void)addMoney:(double)amount;
- (void)subtractMoney:(double)amount;
- (double)closeAccount; // Returns balance
@end
@interface Bank: NSObject
@property (nonatomic, copy) NSArray<Account *> *accounts;
@property (nonatomic, readonly) double totalBalanceInAllAccounts;
- (void)transferMoneyAmount:(double)amount
fromAccount:(Account *)fromAccount
toAccount:(Account *)toAccount;
@end
If it weren’t for the helpful comment, you wouldn’t be able to tell from this header that the library is thread-safe. In other words, you’ve defined thread-safety as an implementation detail.

See this photo in my flickr album
The lights went out at Seven Seas Park (darn copper thieves!). This gave me an opportunity to capture the full moon over the townhomes lining the park’s perimeter. If you look closely you can see a full halo around the moon, courtesy of some light cirrus clouds.
📷 Nikon D800, Nikon 14-24mm f/28 at 14mm, 20 seconds at f/5.6.
Take a listen to NPR’s high quality audio quiz. Go on, take the test. I’ll wait.
All done? How well did you do?
Me? I got 2 out of 6. A 33% hit rate. That’s pretty dismal.
I love listening to high-quality audio recording, especially the fantastic Mastered for iTunes collection. I buy uncompressed ALAC files from hdtracks.com on occasion. I listen to them through my headphones and DAC.
(For the record, I’m using a pair of pretty good headphones: the PSB M4U 1, connected to a pretty good DAC: an Audioquest DragonFly 1.2.)
In 3 of the 4 cases I got wrong, I chose the 320 KB/sec version instead of the uncompressed WAV. I can hear the difference between the uncompressed and compressed versions, but I preferred the compressed versions.
Twenty years of listening to MP3s—both crappy and great—have deeply altered my perception of what a “good” recording sounds like. Like the generation that preferred the warbly, noisy rendition of vinyl rather than the pristine accuracy of CDs, I prefer the rounded, artifact-sprinkled sound of MP3s.
That’s life, I guess. I’ll continue to listen to lossless audio, and who knows? Maybe in another 20 years I’d actually prefer it to MP3s.
Copyright ©2014–2026 Dave Rahardja. All rights reserved.
Any use of this website’s contents without prior written permission is subject to licensing fees.
You may not use any part of this website for machine training.