2013-04-08 51 views
7

我試圖從waitForDataInBackgroundAndNotify中讀取可可中的NSTask的標準錯誤數據。以下代碼讀取流,因此它已經部分工作。NSFileHandleDataAvailableNotification文件反覆無新數據(導致CPU使用率非常高)

我的問題是,有時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]; 
} 

回答

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

你也應該關閉文件。 – 2013-04-08 23:13:03

+4

我很喜歡在文檔中沒有任何地方提到'waitForDataInBackgroundAndNotify'必須在通知到達後再次調用。謝謝! – 2014-05-04 20:03:52

相關問題