Cocoa:插件无法打开应用程序窗口

时间:2010-03-09 12:32:35

标签: cocoa plugins nswindowcontroller

我正在为OsiriX开发一个插件。

在那个应用程序中我有3-4个nib文件。另外在插件中有一些名为PluginFilter的文件(.h& .m),其中存在一个名为 - (long)filterImage:(NSString)menuName的方法,插件开始执行。现在我的问题是,我已经返回启动主窗口的代码在其他.m文件中,我必须使用上面提到的方法调用该文件。

该应用有多个nib文件。我有一个名为PluginFilter的插件名称:

- (long) filterImage:(NSString*) menuName

当通过此方法调用时,插件应该打开一个窗口。定义窗口控制器的代码位于另一个nib中。当我在插件中调用filterimage方法时,窗口永远不会出现。

这是我的filterImage:方法。

#import "XGridInOsiriXFilter.h"
#import "MainWindowController.h"

@implementation XGridInOsiriXFilter

- (void) initPlugin
{

}

- (long) filterImage:(NSString*) menuName
{

    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init];
    [mainWindowController showWindow:self ];
    [mainWindowController release];

    return 0;
}

@end

调用方法不会产生警告或错误,窗口根本无法显示。

2 个答案:

答案 0 :(得分:1)

我认识到这可能有点太迟了但我正在寻找一种方法来做你要求的同样的事情并找到它。您可以使用NSBundle加载所需的nib并将其指向实例化的控制器。像:

@implementation YourPluginFilter

- (void) initPlugin
{
yourWindowController = [[YourWindowController alloc] init];
NSLog(@"Initialized YourWindowController");
}

- (long) filterImage:(NSString*) menuName
{
if (yourWindowController && [NSBundle loadNibNamed:@"YourNibName" owner:yourWindowController]) {
        NSLog(@"Activated yourWindowController");
    return 0;
} else {
    return -1;
}
}

@end

答案 1 :(得分:0)

您通常不会从插件中打开应用程序的主窗口。根据定义,插件并不总是存在,因此您不应该在其中放置关键代码。您也不希望多个插件打开相同的逻辑窗口。

相反,主窗口应该由app delegate正常显示,但如果插件可用,则可以通过插件处理窗口的 内容

主应用程序应该加载和配置主窗口,并且只调用插件来处理窗口的内容。

即便如此,技术上也可以从插件中打开一个窗口,以便(1)插件未加载且未调用方法(插入断点/日志确认)或(2)窗口控制器是配置错误,因此无法打开窗口。测试插件外部的控制器以确认它是否有效。更好的是,将窗口打开代码移到插件外部。

Edit01:

来自评论:

  

我在上面做了一些改动   代码如下

- (long) filterImage:(NSString*) menuName { 
    MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];            
    [mainWindowController showWindow:self ]; 
    [mainWindowController release]; 
    return 0; 
}
  

但是它显示出没有   -init方法发现。为什么它显示这样,因为-init方法是der   在MainWindowController.m文件中

嗯,这里有两个问题。

(1)您将mainWindowController定义为类MainWindowController,但您可以使用类GridSampleMainWindowController对其进行初始化。如果MainWindowControllerGridSampleMainWindowController的子类,这将起作用,但会生成警告。你应该像

一样初始化它
GridSampleMainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];  

MainWindowController *mainWindowController = [[MainWindowController alloc] init:self]; 

(2)释放控制器时没有任何其他对象保留它会杀死它。当窗口控制器死亡时,它会释放它控制的窗口。这很可能就是为什么你什么也看不见。

你应该理清你想要控制器的类,然后将它设置为插件类的保留属性,这样你就可以保持它的窗口。

它抱怨哪种init方法?如果这是插件的实际初始化方法,那么initPlugin什么也不做,只返回void,然后插件永远不会加载。它应该至少看起来像这样:

- (id) initPlugin
{
    self=[super init];
    return self;
}

看起来你来自纯C背景,这对这个环境很有用,但你需要了解Objective-C语言的面向对象部分。你仍然在编写方法,就好像它们是旧式的C函数一样,并且存在重要和经常的微妙差异。

对不起,我昨天错过了这一切。我看到了“插件”并专注于问题的错误方面。

Edit02:

  

不,我不是在谈论我的initPlugin   方法。我在说我的初学者   在那里的方法   MainWindowController.m文件

- (id)init { 
      self = [super initWithWindowNibName:@"MainWindow"]; 
      return self; 
}

这将返回MainWindowController超级类的实例。如果您没有进行任何自定义,则无需覆盖子类中的init方法。只需使用继承版本:

MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"MainWindow"];