Objective c NSString drawInRect:withAttributes:causes';无法识别的选择器发送到实例…';

Objective c NSString drawInRect:withAttributes:causes';无法识别的选择器发送到实例…';,objective-c,cocoa,unrecognized-selector,nscell,nscontrol,Objective C,Cocoa,Unrecognized Selector,Nscell,Nscontrol,我得到了一个非常奇怪的结果:一个方法会导致无法识别的选择器被发送到实例,但它根本不会NSLog()任何东西 我创建了一个自定义NSControl子类,在其中我尝试像这样绘制自定义单元格: - (void)drawRect:(NSRect)dirtyRect { NSLog(@"DrawRect entered!"); [[NSColor grayColor] set]; [NSBezierPath fillRect:[self bounds]]; unsigne

我得到了一个非常奇怪的结果:一个方法会导致
无法识别的选择器被发送到实例
,但它根本不会
NSLog()
任何东西

我创建了一个自定义NSControl子类,在其中我尝试像这样绘制自定义单元格:

- (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;
    }
}
输出:

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'
如您所见,调用了MKMenuCell的
drawWithFrame:inView:
。但是它的
NSLog()
语句的输出不会显示。这里发生了什么?如何解决


编辑:我现在意识到,看着GDB的输出,第一次没有任何问题。这让它变得更加奇怪。

发送的错误选择器,
screenFontWithRenderingMode
,是NSFont上的一种方法。我打赌您不应该为键
NSFontAttributeName
的值设置颜色。你可能应该给它一种字体。

([self.bounds]).size.width
-Argh,为什么不
self.bounds.size.width
?或者:
cRectGetWidth(self.bounds)
@H2CO3对不起,我在一台带有Objective-C1的机器上原型化了这段代码。。。但我想我已经发现了问题(尚未测试):我为键
NSFontAttributeName
设置了颜色。NSString查找
NSFontAttributeName
的值,认为它是NSFont(但它是NSColor)。因此无法识别选择器。错误输出会阻止my NSLog()语句的标准输出流。但这些都没有经过测试。我将把问题留在这里,这样其他人可以看到代码;它可能有多个问题。我已经注意到了这一点(请参阅我对该问题的评论),但将问题留在这里,因为我不确定这是否是唯一的问题。@11684:问题并不是“为我的NSLog()语句阻塞标准输出流”;这是因为它会导致异常,从而结束代码的执行并将应用程序放回最内部的运行循环(或者,在某些情况下,完全终止它)。您的内部方法没有超出您尝试的
drawInRect:withAttributes:
;您的外部方法只进入循环一次。修复异常(不在需要字体的地方添加颜色)将修复循环。好吧,你错了(这听起来很粗鲁,但不是故意的。我不是以英语为母语的人)。循环运行两次(因为数组中的第一个值是nil,这是代码的另一个问题),并且NSLog语句位于引发错误的行之前。我认为
stdout
缓冲了这一点,然后
stderr
插入。之后,应用程序终止而不刷新
stdout
@11684的缓冲区:循环运行两次而不是一次是正确的;我没看到。“数组中的第一个值”必须指第一个单元格的名称,因为第一个单元格本身不能是
nil
-数组不能包含
nil
。对此,我的解释是:只要您将
drawInRect:withAttributes:
发送到一个实际字符串,该字符串将尝试使用无效的属性(您当前在第二个单元格中执行的操作),该字符串将抛出一个异常,该异常实际上会中断循环,并在该点上完全中断您的代码。嘿,我打印的日志包含的日志比第一个日志多。很抱歉,我的评论是基于另一个日志的(我运行了数百次此代码,因为我不明白出错的原因),而该日志恰好有点不同。。。我道歉!
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'