问题
First of all, when debugging and running in Xcode everything works as expected.
But when I try to "share" my app, i.e. make a release build, my NSTask won't output any standardOutput while standardErrors ARE put out. How is that possible?
My code
- (id)initWithWindow:(NSWindow *)window {
self = [super initWithWindow:window];
if (self) {
// Initialization code here.
}
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(readPipe:) name:NSFileHandleReadCompletionNotification object:nil];
return self;
}
-(void) watchFile:(NSNotification *)notification {
NSString *path = [[notification userInfo] valueForKey:@"path"];
task = [[NSTask alloc] init];
[task setLaunchPath:@"/usr/bin/compass"];
[task setCurrentDirectoryPath:path];
NSArray *arguments;
arguments = [NSArray arrayWithObjects: @"watch",@"--boring", nil];
[task setArguments: arguments];
NSPipe *outPipe, *errPipe;
outPipe = [NSPipe pipe];
errPipe = [NSPipe pipe];
[task setStandardOutput: outPipe];
[task setStandardError: errPipe];
[task setStandardInput: [NSPipe pipe]];
standardHandle = [outPipe fileHandleForReading];
[standardHandle readInBackgroundAndNotify];
errorHandle = [errPipe fileHandleForReading];
[errorHandle readInBackgroundAndNotify];
[self setSplitterPosition:0.0f];
[task launch];
}
-(void)readPipe:(NSNotification *)notification {
NSLog(@"reading pipe");
NSData *data;
NSString *text;
if(!([notification object] == standardHandle) && !([notification object] == errorHandle)) {
return;
}
data = [[notification userInfo] objectForKey:NSFileHandleNotificationDataItem];
text = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
if ([data length] == 0) {
//error
[self setSplitterPosition:150.0f];
return;
}
[terminalViewController updateTerminal:text];
if(![text isEqualToString:@"\n"]) [self growlAlert:text title:@"Compapp"];
[text release];
if(task) [[notification object] readInBackgroundAndNotify];
}
回答1:
/usr/bin/compass
is not a binary installed in the standard installation of OSX (I don't have any binary named compass
in my /usr/bin
on my Mac)
So it seems quite logical that when your app is running on another Mac -- that does not have /usr/bin/compass
installed -- and you try to run this task, it can't find it and only output some error on stderr.
回答2:
If you mean after release you are trying to debug, you need to create a file called Entitlements.plist and set Can be debugged before you build and archive.
回答3:
if this is still an open issue for you, then checkout the answer I posted at this link: How to use a determinate NSProgressIndicator to check on the progress of NSTask? - Cocoa
it provides a good template for creating an async NSTask and for reading from standard output or standard error.
来源:https://stackoverflow.com/questions/8254680/nstask-only-returning-standarderror-in-release-build