运行 没有调试器时 NSFileHandle 表现异常 - 一些 NSRunLoop 问题?
NSFileHandle behaving strangely when run without debugger - some NSRunLoop issue?
我正在 Mac 上为 Adobe Premiere 编写一个插件,它会打开一个外部应用程序,然后使用 NSPipe 和 NSFileHandle 从外部应用程序读取标准输出。我知道推荐的方法包括使用 NSNotificationCenter 和 NSFileHandle 的 read In Background And Notify 命令,或者使用 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 时,效果很好。但是,当我 运行 自己首映时,当外部应用程序在其标准输出中放置一行时,不会调用该块(或通知,如果我正在使用该方法)。我假设有一些奇怪的方式,当它的 运行 到 Xcode 时,它的 运行 上的线程有一个 运行 循环,当从 Premiere 启动插件时,该循环不知何故不活动运行宁自己。
我可以解决这个问题的一种方法是让一个循环每秒检查几次是否有东西要从后台线程中的管道的 NSFileHandle 运行ning 中读取。但是,我找不到任何方法来检查是否有要从 NSFileHandle 中读取的内容,而不仅仅是阻塞,直到有东西准备好了(即使有东西准备好了,但由于某种原因,即使没有通过 Xcode 启动,阻塞也会因为某种原因而保持阻塞状态).
所以我希望有两个解决方案之一:
1) 一些方法来纠正 NSRunLoop 的任何问题,即当管道的 NSFileHandle 中有准备好的东西时 notifications/callback 块没有被触发。要么
2) 一些方法来检查管道的 NSFileHandle 中是否有准备好读取的内容,而不会阻塞直到准备好读取内容。
感谢您的帮助!!!!
好吧,看起来真正的问题是,当从 Xcode 中启动所有内容时,我的外部应用程序会在我打印到标准输出时立即刷新标准输出缓冲区,但在没有 Xcode 的情况下启动时] 我需要添加以下行来手动刷新它:
fflush(标准输出);
所以问题在于此,而不是我的插件中的代码没有正确等待和读取管道!
我正在 Mac 上为 Adobe Premiere 编写一个插件,它会打开一个外部应用程序,然后使用 NSPipe 和 NSFileHandle 从外部应用程序读取标准输出。我知道推荐的方法包括使用 NSNotificationCenter 和 NSFileHandle 的 read In Background And Notify 命令,或者使用 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 时,效果很好。但是,当我 运行 自己首映时,当外部应用程序在其标准输出中放置一行时,不会调用该块(或通知,如果我正在使用该方法)。我假设有一些奇怪的方式,当它的 运行 到 Xcode 时,它的 运行 上的线程有一个 运行 循环,当从 Premiere 启动插件时,该循环不知何故不活动运行宁自己。
我可以解决这个问题的一种方法是让一个循环每秒检查几次是否有东西要从后台线程中的管道的 NSFileHandle 运行ning 中读取。但是,我找不到任何方法来检查是否有要从 NSFileHandle 中读取的内容,而不仅仅是阻塞,直到有东西准备好了(即使有东西准备好了,但由于某种原因,即使没有通过 Xcode 启动,阻塞也会因为某种原因而保持阻塞状态).
所以我希望有两个解决方案之一: 1) 一些方法来纠正 NSRunLoop 的任何问题,即当管道的 NSFileHandle 中有准备好的东西时 notifications/callback 块没有被触发。要么 2) 一些方法来检查管道的 NSFileHandle 中是否有准备好读取的内容,而不会阻塞直到准备好读取内容。
感谢您的帮助!!!!
好吧,看起来真正的问题是,当从 Xcode 中启动所有内容时,我的外部应用程序会在我打印到标准输出时立即刷新标准输出缓冲区,但在没有 Xcode 的情况下启动时] 我需要添加以下行来手动刷新它:
fflush(标准输出);
所以问题在于此,而不是我的插件中的代码没有正确等待和读取管道!