Jared Aaron Loo Jared Aaron Loo - 4 months ago 8
Objective-C Question

Unable to replace NSArray derived from output of "ps aux" UNIX command

Im trying to replace the 7th index of the array "lines2". The NSMUTABLEARRAY "lines2" is derived from the UNIX command "ps aux", and I suspect that this command returns an array of NSCFStrings. Im basically trying to replace "Ss" with "Ss (Running)" for now. The problem is that I get a SIGABRT error every time The program reaches the part where it tries to replace the particular array element. The code for my viewController is below.

NSLog(@"myString is :%@", myString);
int processID = [myString intValue];

NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: @"/bin/ps"];

arguments = [NSArray arrayWithObjects: @"aux", [NSString stringWithFormat:@"%i", processID],nil];

[task setArguments: arguments];

NSPipe *pipe;
pipe = [NSPipe pipe];
//[task setStandardOutput: pipe];
[task setStandardOutput:pipe];

NSFileHandle *file;
file = [pipe fileHandleForReading];

[task launch];

NSData *data;
data = [file readDataToEndOfFile];

NSString *string;
string = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];

// NSLog(@"%@",string);


NSArray *lines= [string componentsSeparatedByString:@"\n"];

NSString *lastline = [lines objectAtIndex:[lines count]-2];
// NSLog(@"%@",lastline);



lines2= [lastline componentsSeparatedByString:@" "];
NSLog(@"%@",lines2);
for (int i=0; i<[lines2 count]; i++) {

if([[lines2 objectAtIndex:i] isEqualToString:@""]){
[lines2 removeObjectAtIndex:i];
}

}
for (int i=0; i<[lines2 count]; i++) {

if([[lines2 objectAtIndex:i] isEqualToString:@""]){
[lines2 removeObjectAtIndex:i];
}

}
for (int i=0; i<[lines2 count]; i++) {

if([[lines2 objectAtIndex:7] isEqualToString:@"Ss"]){
[[lines2 objectAtIndex:0] replaceObjectAtIndex:7 withObject:@"SS (Running)"];

}
}


Any help is very much appreciated!

Answer

Please look at the documentation for the method -componentsSeparatedByString:. The signature is:

- (NSArray *)componentsSeparatedByString:(NSString *)separator

Notice the return type is NSArray. This is an immutable object. You must not change it even if inspecting the returned object (say with a debugger or an NSLog) shows it to actually be mutable. You must respect the API contract. (Read the section of the link entitled "receiving mutable objects".)

That said, the immediate cause of your error is this line:

[[lines2 objectAtIndex:0] replaceObjectAtIndex:7 withObject:@"SS (Running)"];
 ^^^^^^^^^^^^^^^^^^^^^^^^ This is wrong

lines2 is an array of strings. [lines2 objectAtIndex: 0] is a string. Why are you sending -replaceObjectAtIndex:withObject: to it?