【发布时间】:2014-10-09 00:38:00
【问题描述】:
我一直想学习如何在 OS X 平台上编写代码,并尝试通过学习如何为系统提供的颜色选择器制作自定义颜色选择器,因为这似乎是一个非常简单的概念。我在 Apple 网站上阅读了一些 documentation 以帮助我入门,因为他们示例中的代码很旧,但我能够转换,因此它使用 ARC 并在 64 位系统上运行。
我的实现:
所有自定义颜色选择器都必须采用NSColorPickingCustom 协议,我已经这样做了。我创建了一个名为Main 的 Nib 文件,在该文件中我将视图连接到 Principal 类中的 IBOutlet 属性。我已经按照协议的要求实现了- (NSView *)provideNewView:(BOOL)initialRequest 函数。在这个函数中,如下所示,我检查了是否有一个选择器可用于确定我在哪个平台上运行,以便我知道我应该调用哪个loadNibNamed 方法。我从发布在 SO 上的 answer 得到这个想法。此外,我的项目的部署目标设置为 10.7。
- (NSView *)provideNewView:(BOOL)initialRequest {
if(initialRequest) {
if ([[NSBundle mainBundle] respondsToSelector:@selector(loadNibNamed:owner:topLevelObjects:)]) {
// We're running on Mountain Lion or higher
[[NSBundle mainBundle] loadNibNamed:@"Main" owner:self topLevelObjects:nil];
} else {
// We're running on Lion
[NSBundle loadNibNamed:@"Main" owner:self];
}
}
return _view;
}
结果:
当我通过我编写的 AppleScript 启动 OS X 颜色选择器时,颜色选择器崩溃并出现以下我从控制台应用程序中提取的错误(我还没有弄清楚如何将 Xcode 调试器与捆绑项目一起使用):
* 由于未捕获的异常 'NSInvalidArgumentException' 导致应用程序终止,原因:'* -[__NSArrayM insertObject:atIndex:]: object cannot be nil' 以 NSException 类型的未捕获异常终止 abort() 调用
错误报告中列出的 Application Specific Backtrace 的前 7 行:
Application Specific Backtrace 1:
0 CoreFoundation 0x00007fff861be25c __exceptionPreprocess + 172
1 libobjc.A.dylib 0x00007fff8680be75 objc_exception_throw + 43
2 CoreFoundation 0x00007fff8607f487 -[__NSArrayM insertObject:atIndex:] + 951
3 AppKit 0x00007fff8787a44f -[NSColorPanel _provideNewViewFor:initialViewRequest:] + 91
4 AppKit 0x00007fff8787a364 -[NSColorPanel setMode:] + 354
5 AppKit 0x00007fff8787ce25 -[NSColorPanel _initWithPickers:] + 1157
6 AppKit 0x00007fff878791fb -[NSColorPanel initWithContentRect:styleMask:backing:defer:] + 792
7 AppKit 0x00007fff87a37437 -[NSPanel init] + 98
其他信息:
如果我将部署目标设置为 10.7,并使用以下功能,颜色选择器应用程序会加载并显示我的自定义颜色选择器:
- (NSView *)provideNewView:(BOOL)initialRequest {
if(initialRequest) {
[NSBundle loadNibNamed:@"Main" owner:self];
}
return _view;
}
如果我将部署目标设置为 10.9,并使用以下功能,颜色选择器应用程序将失败并出现我上面列出的相同错误:
- (NSView *)provideNewView:(BOOL)initialRequest {
if(initialRequest) {
[[NSBundle mainBundle] loadNibNamed:@"Main" owner:self topLevelObjects:nil];
}
return _view;
}
我希望有人可以向我提供有关 loadNibNamed:owner:topLevelObjects 方法调用失败的原因的见解,即使它是用于已弃用的 loadNibNamed:owner: 方法调用的方法。理想情况下,我希望编写我的应用程序以支持新旧系统,而不仅仅是最新系统,这就是为什么我希望它按照我在帖子顶部列出的函数中实现它的方式工作。
【问题讨论】:
标签: objective-c macos cocoa nsbundle