I have a custom NSCell with the following code to display an NSColorPanel when it is clicked:
-(void)setColorFromPanel:(NSColorPanel*)panel{
NSLog(@"COLOR is HERE!");
[self setObjectValue:[panel color]];
}
- (NSUInteger)hitTestForEvent:(NSEvent *)event inRect:(NSRect)cellFrame ofView:(NSView *)controlView{
if(self.isColor){
if([event type]==NSLeftMouseDown){
NSColorPanel *panel=[NSColorPanel sharedColorPanel];
[panel setColor:[self objectValue]];
[panel setShowsAlpha:YES];
[panel setAction:@selector(setColorFromPanel:)];
[panel setTarget:self];
[panel makeKeyAndOrderFront:nil];
}
return NSCellHitContentArea;
}
return NSCellHitNone;
}
This code displays a color picker, however, when I click on a color, it crashes. If if remove the [panel setTarget:self] line, then it works fine, albeit with no effect (because I never receive the color value as there is no target).
Here is the stack trace. The error is EXC_BAD_ACCESS.
#0 0x00007fff8667811c in objc_msgSend ()
#1 0x00007fff87081e9a in -[NSApplication sendAction:to:from:] ()
#2 0x00007fff871fa1cd in -[NSColorPanel _forceSendAction:notification:firstResponder:] ()
#3 0x00007fff871fe384 in -[NSColorPanel setColor:] ()
#4 0x00007fff8721d112 in -[NSColorPickerWheel setColor:] ()
#5 0x00007fff8721d5ae in -[NSColorPickerWheel brightnessSlider:] ()
#6 0x00007fff87081e9a in -[NSApplication sendAction:to:from:] ()
#7 0x00007fff87081df9 in -[NSControl sendAct开发者_运维问答ion:to:] ()
#8 0x00007fff8710d400 in -[NSCell trackMouse:inRect:ofView:untilMouseUp:] ()
#9 0x00007fff873eaf01 in -[NSSliderCell trackMouse:inRect:ofView:untilMouseUp:] ()
#10 0x00007fff8710c215 in -[NSControl mouseDown:] ()
#11 0x00007fff8702634f in -[NSWindow sendEvent:] ()
#12 0x00007fff86f5ba86 in -[NSApplication sendEvent:] ()
#13 0x00007fff86ef24da in -[NSApplication run] ()
#14 0x00007fff86eeb1a8 in NSApplicationMain ()
#15 0x00000001000029bb in main (argc=1, argv=0x7fff5fbff6a0)
You need to post the relevant part of the crash reports/debugger outputs; otherwise, it's hard to guess exactly what went wrong! We're not psychics, you know. The crash report contains valuable info why it crashed.
That said, there's an open-source color-well cell available here. It's only for GC-enabled app, but should be a good start to build upon, if the license of that code fits your usage. Don't re-invent the wheel.
let me add a few words. NSCell
in an NSTableView
is used as a stamp to draw entries for each row and typically is re-used, and it's not that an NSCell
for each row is generated. This doesn't make much sense from the current point of view with abundant memory in a system, but it made sense 15 years ago when NeXTStep was first designed.
Anyway, because of this reason, it's not typically a good idea for a cell to set itself as a target of another object, because that cell tends not to persist. I guess that's what's causing this crash, i.e. NSTableColumn
had already released the cell because it finished using that particular cell. It's generally safer to have a controller class as the target of the panel, not the cell itself.
精彩评论