Looping Multiple NSTasks

Hello. I’m trying to run multiple NSTasks but am finding that when one NSTask completes, all other NSTasks terminate. I think this issue is with NSNotificationCenter, specifically, the line:

NSNotificationCenter's defaultCenter()'s removeObserver_(me)

For example, if taskOne completes first, taskTwo halts mid-run (and vice versa). I have tried setting up unique properties/variables for each task, but this does not appear to resolve the issue. Any insights would be greatly appreciated!!


    property NSNotificationCenter : class "NSNotificationCenter"
    property NSPipe : class "NSPipe"
    property NSTask : class "NSTask"
    property NSString : class "NSString"

-------------------- TASK ONE

on runTaskOne_(sender)
    
    set taskOne to NSTask's alloc's init()
    set outputPipe to NSPipe's pipe()
    taskOne's setStandardOutput_(outputPipe)
    taskOne's setStandardError_(outputPipe)
    taskOne's setLaunchPath_("/path/to/executable")
    taskOne's setArguments_({"-argument"})
    
    NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "taskOneReadPipe:", "NSFileHandleReadCompletionNotification", taskOne's standardOutput()'s fileHandleForReading())
    
    NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "taskOneEndPipe:", "NSTaskDidTerminateNotification", taskOne)
    
    taskOne's standardOutput()'s fileHandleForReading()'s readInBackgroundAndNotify()
    
    taskOne's |launch|()
    
end runTaskOne_

on taskOneReadPipe_(aNotification)
    
    set dataString to aNotification's userInfo's objectForKey_("NSFileHandleNotificationDataItem")
    set newString to ((NSString's alloc()'s initWithData_encoding_(dataString, current application's NSUTF8StringEncoding)))
    
    taskOneOutputLabel's setStringValue_(newString as text)
    aNotification's object()'s readInBackgroundAndNotify()
    
end taskOneReadPipe_

on taskOneEndPipe_(aNotification)
    
    log "taskOne completed"
    
    NSNotificationCenter's defaultCenter()'s removeObserver_(me)
    
    my runTaskOne_(me)
    
end taskOneEndPipe_

-------------------- TASK TWO

on runTaskTwo_(sender)
    
    set taskTwo to NSTask's alloc's init()
    set outputPipe to NSPipe's pipe()
    taskTwo's setStandardOutput_(outputPipe)
    taskTwo's setStandardError_(outputPipe)
    taskTwo's setLaunchPath_("/path/to/executable")
    taskTwo's setArguments_({"-argument"})
    
    NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "taskTwoReadPipe:", "NSFileHandleReadCompletionNotification", taskTwo's standardOutput()'s fileHandleForReading())
    
    NSNotificationCenter's defaultCenter()'s addObserver_selector_name_object_(me, "taskTwoEndPipe:", "NSTaskDidTerminateNotification", taskTwo)
    
    taskTwo's standardOutput()'s fileHandleForReading()'s readInBackgroundAndNotify()
    
    taskTwo's |launch|()
    
end runTaskTwo_

on taskTwoReadPipe_(aNotification)
    
    set dataString to aNotification's userInfo's objectForKey_("NSFileHandleNotificationDataItem")
    set newString to ((NSString's alloc()'s initWithData_encoding_(dataString, current application's NSUTF8StringEncoding)))
    
    taskTwoOutputLabel's setStringValue_(newString as text)
    aNotification's object()'s readInBackgroundAndNotify()
    
end taskTwoReadPipe_

on taskTwoEndPipe_(aNotification)
    
    log "taskTwo completed"
    
    NSNotificationCenter's defaultCenter()'s removeObserver_(me)
    
    my runTaskTwo_(me)
    
end taskTwoEndPipe_


Instead of using removeOberserver:, use removeObserver:name:object: and specify the name of the notification to stop observing. As it stands, you’re turning off all notifications.

It’s amazing how obvious things seem when someone points out the obvious. Thank you Shane!!

Got it working by adding the following to each task’s endPipe:



NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSTaskDidTerminateNotification", taskTwo)
       
 NSNotificationCenter's defaultCenter()'s removeObserver_name_object_(me, "NSFileHandleReadCompletionNotification", taskTwo's standardOutput()'s fileHandleForReading())