코코아:플러그인이 앱 창을 열 수 없습니다
-
18-09-2019 - |
문제
나는 플러그인을 개발 중입니다. 오시리X.
해당 앱에는 3-4개의 nib 파일이 있습니다.또한 플러그인에는 PluginFilter라는 파일(.h & .m)이 있으며, 여기에는 플러그인이 실행을 시작하는 (긴) 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
메서드를 호출하면 경고나 오류가 발생하지 않고 창이 나타나지 않습니다.
해결책
일반적으로 플러그인에서는 앱의 기본 창을 열지 않습니다.정의에 따르면 플러그인은 항상 존재하는 것은 아니므로 플러그인에 중요한 코드를 삽입하면 안 됩니다.여러 플러그인이 동일한 논리 창을 여는 것도 원하지 않습니다.
대신 기본 창은 앱 위임자에 의해 정상적으로 표시되어야 하지만 콘텐츠 플러그인을 사용할 수 있는 경우 해당 창을 플러그인으로 처리할 수 있습니다.
메인 애플리케이션은 메인 창을 로드하고 구성해야 하며 창의 내용을 처리하기 위해 플러그인만 호출해야 합니다.
그럼에도 불구하고 플러그인에서 창을 여는 것이 기술적으로 가능하므로 (1) 플러그인이 로드되지 않고 메소드가 호출되지 않거나(확인을 위해 중단점/로그 삽입) (2) 창 컨트롤러가 잘못 구성되어 창문은 열리지 않습니다.플러그인 외부에서 컨트롤러를 테스트하여 작동하는지 확인하세요.더 나은 방법은 창 열기 코드를 플러그인 외부로 옮기는 것입니다.
편집01:
댓글에서:
다음과 같이 위의 코드를 변경했습니다.
- (long) filterImage:(NSString*) menuName {
MainWindowController *mainWindowController = [[GridSampleMainWindowController alloc] init:self];
[mainWindowController showWindow:self ];
[mainWindowController release];
return 0;
}
그러나 -INIT 방법이 발견되지 않았다는 점을 보여줍니다.mainwindowcontroller.m 파일에서 -init 메소드가 der이기 때문에 이와 같이 표시되는 이유
자, 여기에는 두 가지 문제가 있습니다.
(1) 정의를 설정했습니다. mainWindowController
수업시간에 MainWindowController
하지만 클래스로 초기화하면 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 방법에 대해 이야기하지 않습니다.나는 mainwindowcontroller.m 파일에있는 나의 init 메소드에 대해 이야기하고 있습니다.
- (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