Objective c 为什么WaitForDataInBackground和Notify不';无法使用具有多个参数的实时监视器?
我从其中一个API中找到了以下代码,并尝试使用它对vm_stat 1进行实时监控:Objective c 为什么WaitForDataInBackground和Notify不';无法使用具有多个参数的实时监视器?,objective-c,nstask,nspipe,Objective C,Nstask,Nspipe,我从其中一个API中找到了以下代码,并尝试使用它对vm_stat 1进行实时监控: BOOL terminated = NO; -(void)realTimeMonitor { NSTask *task = [[NSTask alloc] init]; [task setLaunchPath:@"/bin/bash"]; [task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1", nil]]; //wo
BOOL terminated = NO;
-(void)realTimeMonitor
{
NSTask *task = [[NSTask alloc] init];
[task setLaunchPath:@"/bin/bash"];
[task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1", nil]]; //works fine
// [task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1 | /usr/bin/awk '{print $1}'", nil]]; not working
NSPipe *pipe = [NSPipe pipe];
NSPipe *errorPipe = [NSPipe pipe];
[task setStandardOutput:pipe];
[task setStandardError:errorPipe];
NSFileHandle *outFile = [pipe fileHandleForReading];
NSFileHandle *errFile = [errorPipe fileHandleForReading];
[task launch];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(terminated:)
name:NSTaskDidTerminateNotification
object:task];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(outData:)
name:NSFileHandleDataAvailableNotification
object:outFile];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(errData:)
name:NSFileHandleDataAvailableNotification
object:errFile];
[outFile waitForDataInBackgroundAndNotify];
[errFile waitForDataInBackgroundAndNotify];
while(!terminated)
{
if (![[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
{
break;
}
}
}
-(void) outData: (NSNotification *) notification
{
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
NSData *data = [fileHandle availableData];
if ([data length]) {
NSString *currentString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// do something
}
[fileHandle waitForDataInBackgroundAndNotify]; //Checks to see if data is available in a background thread.
}
-(void) errData: (NSNotification *) notification
{
NSLog(@"errData");
NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
[fileHandle waitForDataInBackgroundAndNotify];
}
- (void) terminated: (NSNotification *)notification
{
NSLog(@"Task terminated");
[[NSNotificationCenter defaultCenter] removeObserver:self];
terminated =YES;
}
========
请看setArguments行。第一行工作得非常好“/usr/bin/vm_stat 1”,但是第二行不工作“/usr/bin/vm_stat 1 |/usr/bin/awk'{print$1}'”(根本没有输出),但是如果我在终端上运行它,它工作得非常好。这是为什么?也许
awk
正在缓冲其标准输出流,因为它认为它不会将标准输出流写入tty设备
这可能最终导致完全死锁,因为如果awk
的stdin被填满,并且awk
的stdout上没有使用者,vm_stat
可能无法写入其stdout
因此,请尝试使用其内置的fflush()
函数刷新awk
的标准输出
[task setArguments:[NSArray arrayWithObjects:@"-c", @"/usr/bin/vm_stat 1 | /usr/bin/awk '{print $1; fflush();}'", nil]];
我可以使用(稍加修改)运行您的代码