I ran into a pretty frustrating bug earlier this week. A few weeks ago I decided to flip the switch from GCC 4.2 to Clang 1.0 for building Check Off. Everything seemed to be working in my testing on my development machine, but as I was doing my Mac OS X Leopard sanity check & testing I noticed that I was running into some pretty frustrating crashes and Console messages related when trying to fire up the preference pane.
10/15/09 3:09:25 PM Check Off[197] *** -[NSCFDictionary unregisterHotKey:]: unrecognized selector sent to instance 0x1086b00
unRegisterHotKey is a method in SGHotKeyCenter and it certainly isn’t related to SCFDictionary, NSCFString or any other method I saw it being applied to.
I fumbled with this for a while thinking that i had made a change in my code somewhere to cause the memory to be smashed a bit too soon, but kept coming up with no logical conclusion as to why the code worked without issue in Snow Leopard, but failed miserably in Leopard.
Long story short, I found the answer on the objc-language list from Bill Bumgarner:
The problem is that Clang generates the wrong write barrier for the global assignment; right for Snow Leopard, incompatible with Leopard.
If you look in SGHotKeyCenter, the sharedInstance is indeed a static global, and is being eaten alive far too soon by the collector.
...
static SGHotKeyCenter *sharedCenter = nil;
@implementation SGHotKeyCenter
+ (void)initialize {
...
There are two workarounds for the issue:
- Switch off of Clang until the issue is resolved by Apple. GCC 4.2 works just fine.
Use
NSGarbageCollectorto disable collection on the pointer after assignment.[[NSGarbageCollector defaultCollector] disableCollectorForPointer:sharedCenter];
Hopefully this post will help a few other developers not waste a day’s work trying to figure out what was causing such a weird error.
Here’s your Radar:

