【问题标题】:Plugin crashes when loadNibNamed:owner:topLevelObjects: is called调用 loadNibNamed:owner:topLevelObjects: 时插件崩溃
【发布时间】: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


    【解决方案1】:

    因此,在进行了更多研究并试图了解我的插件遇到的问题之后,SO 上的另一个 post 帮助阐明了当插件调用 loadNibNamed:owner:topLevelObjects 方法时发生了什么。

    我对这个问题的理解是,因为我正在创建一个插件,代码 [NSBundle mainBundle] 返回应用程序的包,在这种情况下,OS X 颜色选择器工具,其中一个名为 Main 的笔尖没有存在。因此,我需要为我的插件获取捆绑包,它可以使用代码[NSBundle bundleForClass:[self class]] 获取。在我实现这个之后,我的插件正确执行了。下面列出的是我更正的代码:

    - (NSView*)provideNewView:(BOOL)initialRequest
    {
        if( initialRequest) {
            NSBundle* bundle = [NSBundle bundleForClass:[self class]];
            if ([bundle respondsToSelector:@selector(loadNibNamed:owner:topLevelObjects:)]) {
                // We're running on Mountain Lion or higher
                [bundle loadNibNamed:@"Main" owner:self topLevelObjects:nil];
            } else {
                // We're running on Lion
                [NSBundle loadNibNamed:@"Main" owner:self];
            }
        }
        return _view;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-10
      • 2021-10-03
      • 1970-01-01
      • 2019-02-22
      • 2016-02-11
      • 2018-10-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多