Вопрос

Я разрабатываю плагин для Осирикс.

В этом приложении у меня есть 3-4 файла с наконечниками.Также в for для плагина есть файлы (.h & .m), называемые PluginFilter, где вызывается метод - (длинный) filterImage:(NSString) присутствует menuName, из которого плагин начинает выполнение.Теперь моя проблема в том, что я вернул код для запуска главного окна в какой-то другой файл .m, и я должен вызвать этот файл, используя метод, упомянутый выше.

Приложение содержит несколько файлов с наконечниками.У меня есть плагин с именем 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

Вызов метода не приводит к появлению предупреждений или ошибок, окно просто не появляется.

Это было полезно?

Решение

Обычно вы не открываете главное окно приложения из плагина.Плагины по определению могут присутствовать не всегда, поэтому вам не следует помещать в них критический код.Вы также не хотели бы, чтобы несколько плагинов открывали одно и то же логическое окно.

Вместо этого главное окно должно отображаться делегатом приложения как обычно, но Содержание часть окна может быть обработана плагином, если плагин доступен.

Основное приложение должно загрузить и настроить главное окно и вызывать плагин только для обработки содержимого окна.

Тем не менее, технически возможно открыть окно из плагина, поэтому либо (1) плагин не загружается и метод не вызывается (вставьте точку останова / журнал для подтверждения), либо (2) контроллер окна неправильно настроен, так что он не открывает окно.Протестируйте контроллер вне плагина, чтобы убедиться, что он работает.А еще лучше, переместите код открытия окна за пределы плагина.

Редактировать 01:

Из комментария:

Я внес некоторые изменения в приведенный выше код следующим образом

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

но он показывает wanring, что метод -init не найден.Почему это отображается так, потому что метод -init является der в файле MainWindowController.m

Что ж, здесь у вас есть две проблемы.

(1) Вы устанавливаете определение mainWindowController по состоянию на начало занятий MainWindowController но вы инициализируете его с помощью class GridSampleMainWindowController.Если MainWindowController является подклассом GridSampleMainWindowController это сработает, но будет генерировать предупреждения.Вместо этого вы должны инициализировать его следующим образом

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 .Я говорю о моем методе init , который есть в файле MainWindowController.m

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

Это вернет экземпляр MainWindowControllerэто супер класс.Если вы не выполняете никаких настроек, вам не нужно переопределять метод init в вашем подклассе.Просто используйте унаследованную версию таким образом:

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

Другие советы

Я понимаю, что это может быть слишком поздно, но я искал способ сделать то же самое, о чем вы просите, и нашел его.Вы можете использовать NSBundle чтобы загрузить желаемый наконечник и указать его на экземпляр контроллера.Нравиться:

@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
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top