2013-04-08 4 views
7

waitForDataInBackgroundAndNotifyを使用して、ココアのNSTaskの標準エラーからデータを読み取ろうとしています。次のコードはストリームを読み込むため、すでに部分的に動作しています。NSFileHandleDataAvailableNotificationファイルが新しいデータなしで繰り返されます(CPU使用率が非常に高くなります)

私が持っている問題は、時々、すべての([data length]戻り0)で新しいデータで繰り返し(毎秒何千回を)発射NSFileHandleDataAvailableNotification開始。私のプロセスでは、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]; 
} 

答えて

9

それで、自分で解決してしまった。 NSFileHandle Class Referenceによれば、availableDataによって返されたNSDataオブジェクトの長さが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]; 
    } 
} 
+0

また、ファイルを閉じる必要があります。 –

+4

通知が届いた後、再び 'waitForDataInBackgroundAndNotify'を呼び出さなければならないということは、どこにもどこにも書かれていません。ありがとう! –

関連する問題