NSCell 的 NSColorPanel

发布于 2024-10-13 00:09:57 字数 1810 浏览 4 评论 0原文

我有一个自定义 NSCell,其中包含以下代码,用于在单击时显示 NSColorPanel:

-(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;
}

此代码显示颜色选择器,但是,当我单击颜色时,它会崩溃。如果删除 [panel setTarget:self] 行,那么它工作正常,尽管没有效果(因为我从未收到颜色值,因为没有目标)。

这是堆栈跟踪。错误是 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 sendAction: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)

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 sendAction: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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

无声情话 2024-10-20 00:09:57

您需要发布崩溃报告/调试器输出的相关部分;否则,很难猜出究竟出了什么问题!你知道,我们不是通灵者。崩溃报告包含崩溃原因的宝贵信息。

也就是说,此处提供了一个开源色孔单元。它仅适用于支持 GC 的应用程序,但如果该代码的许可证适合您的使用,那么应该是一个良好的开始。不要重新发明轮子。


让我补充几句话。 NSTableView 中的 NSCell 用作标记来为每行绘制条目,并且通常会重复使用,并且它不是一个NSCell 都会生成。从当前系统内存充足的角度来看,这没有多大意义,但在 15 年前 NeXTStep 首次设计时就有意义了。

无论如何,由于这个原因,细胞将自己设置为另一个对象的目标通常不是一个好主意,因为该细胞往往不会持久存在。我想这就是导致这次崩溃的原因,即 NSTableColumn 已经释放了该单元格,因为它已完成使用该特定单元格。通常,将控制器类作为面板的目标而不是单元本身更安全。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文