0

我正在为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

调用该方法不会产生警告或错误,窗口根本不会出现。

4

2 回答 2

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
于 2011-04-06T14:54:08.183 回答
0

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

相反,主窗口应该由应用程序委托正常显示,但如果插件可用,则窗口的内容可以由插件处理。

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

即便如此,从技术上来说,从插件打开一个窗口是可行的,因此(1)插件没有被加载并且方法没有被调用(插入断点/日志以确认)或(2)窗口控制器配置错误,因此它不打开窗口。测试插件外部的控制器以确认其工作。更好的是,将窗口打开代码移到插件之外。

编辑01:

来自评论:

我对上面的代码做了一些修改,如下

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

但它显示没有找到 -init 方法。为什么会这样显示,因为 -init 方法在 MainWindowController.m 文件中

好吧,这里有两个问题。

(1)您将定义设置mainWindowController为 class MainWindowController,但使用 class 对其进行初始化GridSampleMainWindowController。If MainWindowController is GridSampleMainWindowControllerthis 的子类将起作用,但会产生警告。你应该像这样初始化它

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 函数一样,并且存在重要且经常是细微的差异。

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

编辑02:

不,我不是在谈论我的 initPlugin 方法。我说的是我在 MainWindowController.m 文件中的 init 方法

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

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

MainWindowController *mainWindowController = [[MainWindowController alloc] initWithWindowNibName:@"MainWindow"]; 
于 2010-03-09T13:54:51.597 回答