我正在为 Mac 上的 Adobe Premiere 编写一个插件,它打开一个外部应用程序,然后使用 NSPipe 和 NSFileHandle 从外部应用程序读取标准输出。我知道这样做的推荐方法包括使用 NSNotificationCenter 以及 NSFileHandle 的 readInBackgroundAndNotify 命令,或者使用 NSFilehandle 的 setReadabilityHandler 方法在输出到达时一次读取一行:
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)通过某种方法来纠正 NSRunLoop 的任何问题,即当管道的 NSFileHandle 中有东西准备好时,通知/回调块不会被触发。或 2) 某种方法来检查管道的 NSFileHandle 中是否有准备好读取的内容,而不会阻塞,直到准备好读取某些内容。
谢谢你的帮助!!!!