2011-10-06 15 views
5

मैं एनएसटीस्क का उपयोग कर रहा हूं, लेकिन जब मैं कार्य को लॉन्च करता हूं तो यह मुख्य धागा को ब्लॉक करता है (इसलिए मैं इसे अपडेट नहीं कर सकता) जब तक कि कार्य समाप्त नहीं हो जाता। यह मेरा कोड है:एनएसटीस्क मुख्य धागे को अवरुद्ध कर रहा है

NSString *hostsforping = @"google.es"; 
    pingdata = [[NSTask alloc] init]; 
    [pingdata setLaunchPath: @"/sbin/ping"]; 

    NSArray *pingargs; 
    pingargs = [NSArray arrayWithObjects: @"-c 5", hostsforping, nil]; 
    [pingdata setArguments: pingargs]; 

    NSPipe *pingpipe; 
    pingpipe = [NSPipe pipe]; 
    [pingdata setStandardOutput: pingpipe]; 

    NSFileHandle *pingfile; 
    pingfile = [pingpipe fileHandleForReading]; 

    [pingdata launch]; 

    NSData *pingdata1; 
    pingdata1 = [pingfile readDataToEndOfFile]; 

    NSString *pingstring; 
    pingstring = [[NSString alloc] initWithData: pingdata1 encoding: NSUTF8StringEncoding]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(taskDidTerminate:) 
               name:NSTaskDidTerminateNotification 
               object:nil]; 
} 
- (void) taskDidTerminate:(NSNotification *)notification { 
    NSLog(@"end"); 
} 

मैं पढ़ रहा है -waitUntilExit मुख्य थ्रेड ब्लॉक करता है, लेकिन मैं इसे का उपयोग नहीं करते, तो मैं मैं गलत क्या कर रही हूं पता नहीं है।

उत्तर

11

पृष्ठभूमि थ्रेड पर कार्य चलाएं, readDataToEndOfFile मुख्य धागे को अवरुद्ध कर रहा है।

// Offload the method onto a background thread, could also use Grand Central Dispatch 
[self performSelectorInBackground:@selector(startTask) withObject:nil]; 


- (void)startTask { 
    NSString *hostsforping = @"google.es"; 
    NSTask *pingdata = [[NSTask alloc] init]; 
    [pingdata setLaunchPath: @"/sbin/ping"]; 

    NSArray *pingargs; 
    pingargs = [NSArray arrayWithObjects: @"-c 5", hostsforping, nil]; 
    [pingdata setArguments: pingargs]; 

    NSPipe *pingpipe; 
    pingpipe = [NSPipe pipe]; 
    [pingdata setStandardOutput: pingpipe]; 

    NSFileHandle *pingfile; 
    pingfile = [pingpipe fileHandleForReading]; 

    [pingdata launch]; 

    NSData *pingdata1;  
    pingdata1 = [pingfile readDataToEndOfFile]; 

    NSString *pingstring; 
    pingstring = [[NSString alloc] initWithData: pingdata1 encoding: NSUTF8StringEncoding]; 
    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(taskDidTerminate:) 
               name:NSTaskDidTerminateNotification 
               object:nil]; 
} 

- (void) taskDidTerminate:(NSNotification *)notification { 
    // Note this is called from the background thread, don't update the UI here 
    NSLog(@"end"); 

    // Call updateUI method on main thread to update the user interface 
    [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:NO]; 
} 
+0

या, एक readabilityHandler जो स्वचालित रूप से निष्पादित हो जाता है, जब आपके कार्य डेटा resp है का उपयोग करें। पाइप में कुछ लिखा है। –

1

के बाद से, आप readDataToEndOfFile उपयोग करते हैं, आप अंतर्निहित कहावत है कि आपके NSTask एक अवरुद्ध निष्पादन की जरूरत है कर रहे हैं। मैं आपको dispatch_async का उपयोग करके, जीसीडी ब्रैकेट के आसपास अपना कोड लपेटने का सुझाव दे सकता हूं। उदाहरण के लिए:

- (void)executeShellScript { 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ 
     NSString *execPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"myScript.sh"]; 

     NSPipe *pipe = [NSPipe pipe]; 
     NSFileHandle *file = pipe.fileHandleForReading; 

     NSTask *task = [[NSTask alloc] init]; 
     task.launchPath = @"/bin/sh"; 
     task.arguments = @[execPath]; 
     task.standardOutput = pipe; 

     [task launch]; 

     NSData *data = [file readDataToEndOfFile]; //readDataToEndOfFile is blocking the main thread. 
     [file closeFile]; 
     NSString *bashOutput = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding]; 

     NSLog (@"shell returned:\n%@", bashOutput); 
    }); 
} 
संबंधित मुद्दे

 संबंधित मुद्दे