2017-04-02 1 views
0

Mac에서 Adobe Premiere 용 플러그인을 쓰고 있는데, 외부 응용 프로그램을 연 다음 NSPipe 및 NSFileHandle을 사용하여 외부 응용 프로그램의 표준 출력을 읽습니다. 도착하는대로 나는이 백그라운드에서 NSFileHandle의 읽기와 함께 NSNotificationCenter를 사용하거나 포함 그리고 명령을 통지하거나 한 번에 출력을 라인을 읽을 NSFilehandle의 setReadabilityHandler 방법을 사용 할 수있는 권장 방법을 알고NSFileHandle은 디버거없이 실행될 때 이상하게 작동합니다. 일부 NSRunLoop 문제입니까?

NSTask appTask... // my task which is launching the external app 
NSPipe* myPipe = [[NSPipe alloc] init]; 
[appTask setStandardOutput:[myPipe fileHandleForReading]]; 
[[myPipe fileHandleForWriting] setReadabilityHandler:^(NSFileHandle *file) { 
    NSData* dataRead = [file availableData]; 
    if (dataRead != nil) { 
     printf("Read a line\n"); 
    } 
}]; 

디버거가 연결되어있는 Xcode에서 Premiere를 시작하면 잘 작동합니다. 그러나 Premiere를 독자적으로 실행할 때 외부 응용 프로그램이 표준 출력에 줄을 입력하면 블록 (또는 해당 메서드를 사용하는 경우 알림)이 호출되지 않습니다. 몇 가지 이상한 방법이 있다고 가정합니다. Xcode를 실행하면 실행중인 스레드가 자체적으로 실행되는 Premiere에서 플러그인을 시작할 때 실행되지 않는 루프가 실행됩니다.

이 문제를 해결할 수있는 방법은 백그라운드 스레드에서 실행중인 파이프의 NSFileHandle에서 읽어야 할 것이 있는지 여부를 몇 초마다 점검하는 루프를 만드는 것입니다. 그러나 NSFileHandle에서 무언가 준비가 될 때까지 읽을 필요가 있는지 확인할 방법이 없습니다 (Xcode를 통해 실행되지 않을 때 뭔가 준비가되어 있어도 블록킹이 막히지 않습니다).

1) 파이프의 NSFileHandle에 준비가되었을 때 알림/콜백 블록이 트리거되지 않는 NSRunLoop의 문제를 해결하는 방법이 있습니다. 또는 2) 뭔가 읽을 준비가 될 때까지 블로킹하지 않고 파이프의 NSFileHandle에서 읽을 준비가되었는지 확인할 수있는 방법이 있습니다.

도움 주셔서 감사합니다. !!!!

답변

0

글쎄, 실제 문제는 Xcode에서 모든 것을 시작할 때 내 외부 앱이 stdout으로 인쇄했을 때 즉시 stdout 버퍼를 플러시하지만 Xcode없이 실행하면 다음 행을 추가해야한다는 것입니다. 수동으로 플러시하십시오 :

fflush (stdout);

그래서 문제는 플러그인에서 코드를 제대로 기다리지 않고 파이프에서 읽지 않는 코드 때문이 아닙니다.

관련 문제