8

NSTaskを使用して Cocoaの a の標準エラーからデータを読み込もうとしていますwaitForDataInBackgroundAndNotify。次のコードはストリームを読み取るため、すでに部分的に機能しています。

私が抱えている問題は、新しいデータがまったくない状態で (毎秒数千回) が繰り返し発火し始めることがあることです( return NSFileHandleDataAvailableNotification) 。その後、プロセスが大量の CPU を使用し始め、マシンの速度が低下して停止します。過去にこのようなことをしたことがある人はいますか?前もって感謝します。[data length]0

/**
 * 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 に答える