2012-12-06 97 views
7

我試圖運行一個簡單的bash腳本使用NSTask並將輸出指向文本視圖。一旦執行任務,我的應用程序的CPU使用率爲100%,儘管這是一個簡單的echo(現在)。使用NSTask和NSPipe導致100%的CPU使用率

我創建了一個完全新的項目來隔離問題:

@interface AppDelegate() 
@property (nonatomic) NSTask *task; 
@property (nonatomic) NSPipe *pipe; 
@end 

@implementation AppDelegate 
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    self.pipe = [NSPipe pipe]; 
    self.pipe.fileHandleForReading.readabilityHandler = ^(NSFileHandle *h) { 
     NSLog(@"Read: %@", [h readDataToEndOfFile]); 
    }; 

    self.task = [[NSTask alloc] init]; 
    self.task.launchPath = @"/bin/bash"; 
    self.task.arguments = @[@"-c", @"echo test"]; 
    self.task.standardOutput = self.pipe; 
    [self.task launch]; 
} 
@end 

它是正確執行和輸出(作爲NSData),同時記錄NSLog

PipeTest[3933:2623] Read: <74657374 0a> 

然而CPU使用率保持在100%,直到我終止我的應用程序。

編輯:

時間探查測試返回下面的列表中,但我不知道如何解釋這一點。

enter image description here

回答

9

文件句柄保持打開狀態?

@interface AppDelegate() 
@property (nonatomic) NSTask *task; 
@property (nonatomic) NSPipe *pipe; 
@end 

@implementation AppDelegate 
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification 
{ 
    self.pipe = [NSPipe pipe]; 
    self.pipe.fileHandleForReading.readabilityHandler = ^(NSFileHandle *h) { 
     NSLog(@"Read: %@", [h readDataToEndOfFile]); 
     [h closeFile]; 
    }; 

    self.task = [[NSTask alloc] init]; 
    self.task.launchPath = @"/bin/bash"; 
    self.task.arguments = @[@"-c", @"echo test"]; 
    self.task.standardOutput = self.pipe; 
    [self.task launch]; 
} 

閉幕式上NSFileHandleh的文件,似乎你的CPU使用率恢復正常。

+1

這太棒了,謝謝!你還可以解釋*爲什麼CPU會如此反應以打開文件句柄? –

2

,如果應用程序(在我的埃爾卡皮坦觀察4K)的寫入速度比NSFileHandle的實現緩衝區的更多建議的代碼將無法正常工作。 [readDataToEndOfFile]往往會一次讀取4K,因此此示例可能會過早關閉緩衝區。爲您的處理程序提供更強大且同樣無法識別的方法是:

NSData *data = [h readDataToEndOfFile]; 
if (data.length) { 
    NSLog(@"Read: %@", data); 
} else { 
    [h closeFile]; 
}