2012-12-06 12 views
7

का कारण बनता है मैं एनएसटीस्क का उपयोग करके एक साधारण बैश स्क्रिप्ट चलाने की कोशिश कर रहा हूं और आउटपुट को टेक्स्ट व्यू पर निर्देशित करता हूं। एक बार कार्य निष्पादित हो जाने के बाद, मेरे ऐप का सीपीयू उपयोग 100% है, भले ही यह एक साधारण echo (अभी के लिए) है।एनएसटीस्क और एनएसपीआईपी का उपयोग 100% सीपीयू उपयोग

@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

यह बहुत अच्छा है, धन्यवाद! क्या आप यह भी समझा सकते हैं कि * सीपीयू इस तरह प्रतिक्रिया करता है कि खुले फ़ाइल हैंडल को छोड़ दिया जाए? –

2

यदि ऐप एनएसफ़ाइलहैंडल के कार्यान्वयन बफर (एल कैपिटन पर मेरे अवलोकन में 4K) से अधिक लिखता है तो सुझाया गया कोड काम नहीं करेगा। [एच readDataToEndOfFile] एक समय में 4K पढ़ने के लिए जाता है, इसलिए यह उदाहरण समय से बफर को बंद कर सकता है। आपके हैंडलर के लिए एक और मजबूत और समान रूप से अनियंत्रित दृष्टिकोण यह है:

NSData *data = [h readDataToEndOfFile]; 
if (data.length) { 
    NSLog(@"Read: %@", data); 
} else { 
    [h closeFile]; 
} 
संबंधित मुद्दे