The problem is actually a few lines above, in the call to _AFSwitchControlPartRects.
- (void)mouseDown:(NSEvent *)event {
NSRect textRect, backgroundRect;
_AFSwitchControlPartRects([self bounds], &textRect, &backgroundRect);
NSRect slotRect = _AFSwitchControlInsetBackgroundRect(backgroundRect);
NSRect knobRect = _AFSwitchControlKnobRectForInsetBackground(slotRect, _offset);
The second argument to _AFSwitchControlPartRects, &textRect is a pointer to a rect.
However in the implementation of the function, that parameter is supposed to be a pointer to enough space for two rects.
NS_INLINE void _AFSwitchControlPartRects(NSRect bounds, NSRect *textRects, NSRect *backgroundRect) {
NSDivideRect(bounds, textRects, backgroundRect, NSWidth(bounds)/5.0, NSMinXEdge);
textRects[1] = _AFSwitchControlInsetTextRect(NSOffsetRect(textRects[0], NSWidth(*backgroundRect), 0));
textRects[0] = _AFSwitchControlInsetTextRect(textRects[0]);
When this writes to textRects[1], it's scribbling on -mouseDown's stack. Buffer overflow.
It looks to me like it's happening to clobber self, so the next dereference of self will die. This happens to be the use of _offset.