8

我正在尝试NSTask使用waitForDataInBackgroundAndNotify. 以下代码确实读取了流,因此它已经部分工作了。

我遇到的问题是,有时NSFileHandleDataAvailableNotification开始重复触发(每秒数千次)而根本没有新数据([data length]返回0)。然后我的进程开始使用大量 CPU,使机器停止运行。你们有没有人在过去遇到过这样的事情?提前致谢。

/**
 * Start reading from STDERR
 *
 * @private
 */

- (void)startReadingStandardError {
    NSFileHandle *fileHandle = [_task.standardError fileHandleForReading];
    [[NSNotificationCenter defaultCenter] addObserver:self
                                             selector:@selector(errorData:)
                                                 name:NSFileHandleDataAvailableNotification
                                               object:fileHandle];
    [fileHandle waitForDataInBackgroundAndNotify];
}

/**
 * Fired whenever new data becomes available on STDERR
 *
 * @private
 */

-(void) errorData: (NSNotification *) notification
{
    NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
    NSData *data = [fileHandle availableData];

    if ([data length]) {
       // consume data
    }

   [fileHandle waitForDataInBackgroundAndNotify];
}
4

1 回答 1

10

所以,最终还是自己解决了。根据NSFileHandle Class Reference,如果NSData返回的对象availableData的长度为0,则表示已到达文件末尾。我没有正确处理这个案子。这为我修复了它:

/**
 * Fired whenever new data becomes available on STDERR
 *
 * @private
 */

-(void) errorData: (NSNotification *) notification
{
    NSFileHandle *fileHandle = (NSFileHandle*) [notification object];
    NSData *data = [fileHandle availableData];

    if ([data length]) {
        // consume data
        // ...

        [fileHandle waitForDataInBackgroundAndNotify];
    } else {
        // EOF was hit, remove observer
        [[NSNotificationCenter defaultCenter] removeObserver:self name:NSFileHandleDataAvailableNotification object:fileHandle];
    }
}
于 2013-04-08T20:05:24.740 回答