NSString drawInRect:withAttributes: causes 'unrecognized selector sent to instance ...'

cocoa, nscell, nscontrol, objective-c, unrecognized-selector

Solution

The bad selector being sent, `screenFontWithRenderingMode`, is a method on NSFont. I'm betting that you shouldn't be setting a color for the value of the key `NSFontAttributeName`. You should probably give it a font.

Problem

I got something really strange: a method causes `unrecognized selector sent to instance`, but doesn't `NSLog()` anything at all. I made a custom NSControl subclass, where I try to draw my custom cells like this: ``` - (void)drawRect:(NSRect)dirtyRect { NSLog(@"DrawRect entered!"); [[NSColor grayColor] set]; [NSBezierPath fillRect:[self bounds]]; unsigned int i, count = [cells count]; NSRect cellRect = NSMakeRect(0, 0, ([self bounds]).size.width, cellHeight); for (i = 0; i < count; i++) { NSLog(@"Drawing cell %d at: %@", i, NSStringFromRect(cellRect)); MKMenuCell *cell = [cells objectAtIndex:i]; [cell drawWithFrame:cellRect inView:self]; cellRect.origin.y += cellHeight; } } ``` And `-[MKMenuCell drawWithFrame:inView:]`: ``` - (void)drawWithFrame:(NSRect)bounds inView:(NSView *)controlView { NSLog(@"-drawWithFrame:inView:"); NSMutableDictionary *strAttribs = [[NSMutableDictionary alloc] init]; [strAttribs setObject:[NSColor blackColor] forKey:NSFontAttributeName]; [name drawInRect:bounds withAttributes:strAttribs]; // "unrecognized selector sent ..." is caused by this method call. } ``` The output: ``` 2013-03-11 18:46:54.823 MacOverflow[738:a0f] DrawRect entered! 2013-03-11 18:46:54.826 MacOverflow[738:a0f] Drawing cell 0 at: {{0, 0}, {176, 30}} 2013-03-11 18:46:54.826 MacOverflow[738:a0f] -drawWithFrame:inView: 2013-03-11 18:46:54.827 MacOverflow[738:a0f] Drawing cell 1 at: {{0, 30}, {176, 30}} 2013-03-11 18:46:54.828 MacOverflow[738:a0f] -drawWithFrame:inView: 2013-03-11 18:46:54.828 MacOverflow[738:a0f] -[NSCachedWhiteColor screenFontWithRenderingMode:]: unrecognized selector sent to instance 0x100512920 2013-03-11 18:46:54.829 MacOverflow[738:a0f] An uncaught exception was raised 2013-03-11 18:46:54.831 MacOverflow[738:a0f] -[NSCachedWhiteColor screenFontWithRenderingMode:]: unrecognized selector sent to instance 0x100512920 2013-03-11 18:46:54.834 MacOverflow[738:a0f] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCachedWhiteColor screenFontWithRenderingMode:]: unrecognized selector sent to instance 0x100512920' *** Call stack at first throw: ( 0 CoreFoundation 0x00007fff88c26784 __exceptionPreprocess + 180 1 libobjc.A.dylib 0x00007fff858ddf03 objc_exception_throw + 45 2 CoreFoundation 0x00007fff88c80110 +[NSObject(NSObject) doesNotRecognizeSelector:] + 0 3 CoreFoundation 0x00007fff88bf88ef ___forwarding___ + 751 4 CoreFoundation 0x00007fff88bf4a38 _CF_forwarding_prep_0 + 232 5 AppKit 0x00007fff89afcfae +[NSStringDrawingTextStorage _fastDrawString:attributes:length:inRect:graphicsContext:baselineRendering:usesFontLeading:usesScreenFont:typesetterBehavior:paragraphStyle:lineBreakMode:boundingRect:padding:scrollable:] + 402 6 AppKit 0x00007fff896db539 _NSStringDrawingCore + 1588 7 MacOverflow 0x00000001000159b7 -[MKMenuCell drawWithFrame:inView:] + 229 8 MacOverflow 0x0000000100015f1e -[MKMenuControl drawRect:] + 595 9 AppKit 0x00007fff896d6cc5 -[NSView _drawRect:clip:] + 3390 10 AppKit 0x00007fff896d5938 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 1325 11 AppKit 0x00007fff896d5ca2 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2199 12 AppKit 0x00007fff896d5ca2 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2199 13 AppKit 0x00007fff896d5ca2 -[NSView _recursiveDisplayAllDirtyWithLockFocus:visRect:] + 2199 14 AppKit 0x00007fff896d400a -[NSView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 767 15 AppKit 0x00007fff896d3b2c -[NSThemeFrame _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:] + 254 16 AppKit 0x00007fff896d03de -[NSView _displayRectIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:] + 2683 17 AppKit 0x00007fff89649c0e -[NSView displayIfNeeded] + 969 18 AppKit 0x00007fff89611c3b -[NSWindow _reallyDoOrderWindow:relativeTo:findKey:forCounter:force:isModal:] + 1050 19 AppKit 0x00007fff896117d2 -[NSWindow orderWindow:relativeTo:] + 94 20 AppKit 0x00007fff895dd974 -[NSIBObjectData nibInstantiateWithOwner:topLevelObjects:] + 1726 21 AppKiProgram received signal: “SIGABRT”. t 0x00007fff895dba91 loadNib + 226 22 AppKit 0x00007fff895dafa1 +[NSBundle(NSNibLoading) _loadNibFile:nameTable:withZone:ownerBundle:] + 248 23 AppKit 0x00007fff895dadd9 +[NSBundle(NSNibLoading) loadNibNamed:owner:] + 326 24 AppKit 0x00007fff895d835b NSApplicationMain + 279 25 MacOverflow 0x0000000100000ef9 main + 33 26 MacOverflow 0x0000000100000ed0 start + 52 27 ??? 0x0000000000000001 0x0 + 1 ) terminate called after throwing an instance of 'NSException' ``` As you can see `MKMenuCell`'s `drawWithFrame:inView:` is called. but the output from its `NSLog()` statement isn't displayed. What is happening here? How to solve it? EDIT: I now realize, looking at the GDB output, the first time nothing goes wrong. This makes it even stranger.

Original source