问题
I'm having trouble executing different NSTask's. Same launchPath
, different arguments
. I have a class who's instances administer own NSTask
objects and depending on arguments those instances were initialized with - dependent NSTask
object is being created. I have two initializers:
// Method for finished task
- (void)taskFinished:(NSNotification *)aNotification {
[myTask release];
myTask = nil;
[self createTask];
}
// Designated initializer
- (id) init {
self = [super init];
if (self != nil) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(taskFinished:)
name:NSTaskDidTerminateNotification
object:nil];
[self createTask];
}
return self;
}
// Convenience initializer
- (id)initWithCommand:(NSString *)subCommand {
self = [self init];
if (self)
{
[self setCommand:subCommand];
}
return self;
}
And here 's the createTask
method:
- (void)createTask {
// myTask is a property defined as NSTask*
myTask = [[NSTask alloc] init];
[myTask setLaunchPath:@"/usr/bin/executable"];
}
The actions are executed via selecting different rows in NSOutlineView (using PXSourceList as a wrapper):
- (void)sourceListSelectionDidChange:(NSNotification *)notification {
id sourceList = [notification object];
NSIndexSet *selection = [sourceList selectedRowIndexes];
NSString *identifier = [[sourceList itemAtRow:[selection firstIndex]] identifier];
// this way `/usr/bin/executable ${identifier}` is being created
MyCommand *command = [[MyCommand alloc] initWithSubcommand:identifier];
// this method executes [myTask launch];
[command execute]
}
The problem is that only first one gets executed. The second ones does not even trigger "click" event (via target-action). I think it could be cause of launchPath I'm trying to use, 'cause simple /bin/ls
works fine. The same command in terminal has 0 return value (i.e. all is fine). Any guides or gotchas are much appreciated.
回答1:
I can't comprehend why... but have read from numerous places that NSTask CAN ONLY be run once....
Using NSTask, your program can run another program as a subprocess and can monitor that program’s execution. NSTask creates a separate executable entity; unlike NSThread, it does not share memory space with the parent process. By default, a task inherits several characteristics of its parent's environment: the current directory, standard input, standard output, standard error, and the values of any environment variables. If you want to change any of these, e.g., the current directory, you must set a new value before you launch the task. A task’s environment is established once it has launched.
An NSTask can only be run once. Subsequent attempts to run an NSTask raise an error.
If you run a task from a document in a document-based application, you should (at the very least) send the terminate message to the task instance in the cleanup code for the document. See also NSTaskTermination for more discussion.
This seems ridiculous... I will research and post back if I find any info the contradicts this source, (although it is usually reliable.)
回答2:
If you care to wade the murky waters that surround PyObjC, you can easily use the subprocess
mechanism of Python.. over, and over, and over. Oh yeah.
来源:https://stackoverflow.com/questions/2846747/nstask-executed-only-once