Cocoa:插件无法打开应用程序窗口
我正在为 OsiriX 开发一个插件。
在该应用程序中我有 3-4 个 nib 文件。另外,在插件中,还有名为 PluginFilter 的文件(.h 和 .m),其中存在名为 - (long) filterImage:(NSString) menuName 的方法,插件从该文件开始执行。现在我的问题是,我已经返回启动主窗口的代码位于其他一些 .m 文件中,我必须使用上面提到的方法调用该文件。
该应用程序有多个 nib 文件。我有一个名为 PluginFilter 的插件,调用者为:
- (long) filterImage:(NSString*) menuName
以此方法调用时,插件应打开一个窗口。定义窗口控制器的代码位于另一个笔尖中。当我在插件中调用 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
调用该方法不会产生警告或错误,窗口根本不会出现。
I am developing an plugin for OsiriX.
In that app i have 3-4 nib files. Also in for plugin there are files (.h & .m) called PluginFilter where method called - (long) filterImage:(NSString) menuName is present from which the plugin start execution. Now my problem is that, I have return the code to launch main window is in some other .m file and I have to call that file using the method mentioned above.
The app has multiple nib files. I have a plugin name PluginFilter called by:
- (long) filterImage:(NSString*) menuName
The plugin should open a window when called by this method. The code that defines the window controller is in another nib. When I call the filterimage
method in the plugin, the window never appears.
Here is my filterImage:
method.
#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
Calling the method produces not warnings or errors, the window simply fails to appear.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我意识到这可能来得太晚了,但我一直在寻找一种方法来完成您所要求的同样的事情并找到了它。您可以使用 NSBundle 加载所需的笔尖并将其指向实例化的控制器。喜欢:
I recognize this may be coming a little too late but I was looking for a way to do the same thing you are asking for and found it. You can use
NSBundle
to load the desired nib and point it to an instantiated controller. Like:您通常不会从插件打开应用程序的主窗口。根据定义,插件并不总是存在,因此您不应将关键代码放入其中。您也不希望多个插件打开同一个逻辑窗口。
相反,主窗口应正常由应用程序委托显示,但窗口的内容可以由插件处理(如果插件可用)。
主应用程序应加载并配置主窗口,并且仅调用插件来处理窗口的内容。
即便如此,从技术上来说,从插件打开窗口是可能的,因此(1)插件未加载且方法未调用(插入断点/日志进行确认)或(2)窗口控制器配置错误,因此它不打开窗户。在插件外部测试控制器以确认其工作正常。更好的是,将窗口打开代码移到插件之外。
Edit01:
来自评论:
那么,这里有两个问题。
(1) 将
mainWindowController
定义为类MainWindowController
,但使用类GridSampleMainWindowController
对其进行初始化。如果MainWindowController
是GridSampleMainWindowController
的子类,这将起作用,但会生成警告。您应该像或
(2) 那样初始化它,或者 (2) 释放控制器,而没有任何其他对象保留它,这会杀死它。当窗口控制器死亡时,它会释放它控制的窗口。这很可能就是您什么也看不到的原因。
您应该弄清楚您希望控制器成为哪个类,然后将其设置为插件类的保留属性,以便可以将其保留在其窗口中。
它抱怨哪个
init
方法?您的initPlugin
不执行任何操作并返回void
如果这是插件的实际初始化方法,则该插件将永远不会加载。它至少应该是这样的:看起来您来自纯 C 背景,这非常适合这个环境,但您需要了解 Objective-C 语言的面向对象部分。您仍在编写方法,就好像它们是老式 C 函数一样,并且存在重要且通常是微妙的差异。
抱歉我昨天错过了这一切。我看到了“插件”并关注了问题的错误方面。
编辑02:
这将返回 MainWindowController 超类的实例。如果您不进行任何自定义,则无需重写子类中的 init 方法。只需使用继承的版本即可:
You would normally not open the app's main window from a plugin. Plugins by definition my not always be present so you should not put critical code in them. Neither would you want multiple plugins opening the same logical window.
Instead, the main window should be displayed by the app delegate as normal but the content of the window can be processed by a plugin if the plugin is available.
The main application should load and configure the main window and only call the plugin to process the contents of the window.
Even so it is technically possible to open a window from a plugin so either (1) the plugin is not being loaded and the method is not being called (insert breakpoint/log to confirm) or (2) the window controller is misconfigured so that it does not open the window. Test the controller outside the plugin to confirm it works. Better yet, move the window opening code outside the plugin.
Edit01:
From comment:
Well, you have two problems here.
(1) You set define
mainWindowController
as of classMainWindowController
but you initialize it with classGridSampleMainWindowController
. IfMainWindowController
is a subclass ofGridSampleMainWindowController
this will work but will generate warnings. You should instead initialize it likeor
(2) You release the controller without any other object retaining it which will kill it. When a window controller dies it deallocates the windows it controls. This is most likely why you see nothing.
You should sort out what class you want the controller to be and then set it as a retained property of the plugin class so you can keep it an its window around.
Which
init
method is it complaining about? YourinitPlugin
does nothing and returns avoid
if that is the plugin's actual initialization method then the plugin will never load. It should at least look like this:It looks like you come from a pure C background which is great for this environment but you need to learn about the object oriented parts of the Objective-C language. You're still writing methods as if they were old school C functions and there are important and oft times subtle differences.
Sorry I missed all this yesterday. I saw "plugin" and focused on the wrong aspect of the problem.
Edit02:
This will return an instance of the
MainWindowController
's super class. If you're not doing any customization you have no need to override the init method in you subclass. Just use the inherited version thusly: