I am trying to run a simple shell command that runs and returns text rather quickly inside of a loop of indeterminate size at compile time that is generated by an NSArray. In scripting languages like perl, I would be able to do something like this:
for(i=0;i<=$myinputarraysize;i++){
$output[i]=`/my/task $inputarray[i]`;
}
This would build a new array for me from the expected output of my task. In Obj-C this seems to be much more difficult and a bit confusing to me. Right now my loop looks like this:
for(int i=0; i<[inputarray count]; i++){
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath:nsdchat];
NSArray *args;
args = [NSArray arrayWithObjects:@"/my/task", [inputarray objectAtIndex:i], nil];
[task setArguments:args];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput:pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *desc;
desc = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
desc = [string stringByReplacingOccurrencesOfString:@"\n" withString:@""];
[descriptions insertObject:desc atIndex:i];
[task release];
[args release];
[pipe release];
[file release];
[data release];
}
My goal is to fill descriptions (an NSMutableArray) with the output from my task (which I know is always a string and always ends in a newline that I want to strip out). It seems I’m missing something about memory releasing as when I run this and NSLog the output, I get the same result for the entire count of the loop.
Is there any easier or more way to loop through simple tasks like this? Am I overcomplicating it for myself?
First of all, there’s no need to do most of that work inside the loop.
task,pipeandfileall look like they could be handled outside the loop. You should also consider using Objective-C 2.0 dot syntax and fast enumeration to cut things down a little.More significantly:
This says that the first argument passed to the executable at path
ndschatis/my/task. Which doesn’t seem to match your PERL usage. Probably you want just:Or, with the style comments taken into account:
EDIT: you’re also releasing a lot of objects you don’t own, which as well as adding heft to your code is a memory management error possibly leading to a crash. So, to cut the whole thing down and correct that fault: