Unable to create NSMutableArray using for-loop - iphone

i want to have an array with values "25 kg", "26 kg"... "149 kg", "150 kg". To simplify task i wrote this:
-(NSMutableArray*)weightArray{
NSMutableArray *myArray;
for (int i=25; i++; i<150){
NSString *weightString;
weightString = [NSString stringWithFormat:#"%d kg", i];
[myArray addObject:weightString];
}
return myArray;
}
And then in viewDidload in my view i wrote: NSLog (#"%#", [self weightArray]);
But it looks like it's not working. I might be missing something obvious like syntax. Why is it not working?
UPDATE:
Finally i found a solution - first, i declare weightArray in #implementation section, then i wrote:
-(void)fillingArray{
if (!weightArray){
for (int i=25; i<150 ;i++){
NSString *weightString = [[NSMutableArray alloc] init];
weightString = [NSString stringWithFormat:#"%d kg", i];
[weightArray addObject:weightString];
NSLog(#"%#", weightString);
}
}
}
In viewDidLoad i wrote:
[self fillingArray];
NSLog(#"%#", weightArray);
I think, my problem was in that string NSLog(#"%#", [self weightArray]); In square brackets it suppose to be method name, but i was trying to point at array, and nothing happening.

There are 3 problems with what you are doing.
You need to create your array like this: NSMutableArray *myArray = [[NSMutableArray alloc] init]; so that it will actually exist.
Your NSLog needs to be NSLog (#"%#", [self weightArray]); since you are lgging an array and not a number.
(thanks rmaddy for pointing this out) The 2nd and 3rd part of your for statement are reversed. So, i++ is your condition and is always non-zero. This infinite loop is what causes your machine to lock up.
EDIT: Here's a better way that only creates the array once.
-(NSMutableArray*)weightArray{
static NSMutableArray *myArray;
if (!myArray){
myArray = [[NSMutableArray alloc] init];
for (int i=25; i<150 ;i++){
NSString *weightString;
weightString = [NSString stringWithFormat:#"%d kg", i];
[myArray addObject:weightString];
}
}
return myArray;
}

You don't allocate and initialize the array. So it has an indeterminate value, and your program invokes undefined beahvior. Create it actually:
NSMutableArray *myArray = [NSMutableArray new];

Related

add data to NSMUtableArrray with keys by for loop

I'm new in iPhone, I want to add elements to NSMutableArray with each element's name
I created a MutableArray for keys , then other array for elements that I get them from object called Pages.
I wrote the following code
NSMutableArray *myArray;
NSMutableArray *arrayKey = [[NSMutableArray alloc] initWithObjects:#"b_pag_id", #"b_pag_bo_id", #"b_pag_num", #"b_pag_note", #"b_page_mark", #"b_page_stop", #"b_pag_user_id", nil];
for (int x=0; x<[pages count]; x++) {
Pages *myPages = (Pages *)[self.pages objectAtIndex:x];
NSString *b_pag_id2 = [NSString stringWithFormat:#"%d",myPages.b_pag_id];
NSString *b_pag_bo_id2 = [NSString stringWithFormat:#"%d",myPages.b_pag_bo_id];
NSString *b_pag_num2 = [NSString stringWithFormat:#"%d",myPages.b_pag_num];
NSString *b_pag_note2 = myPages.b_pag_note;
NSString *b_page_mark2 = [NSString stringWithFormat:#"%d",myPages.b_page_mark];
NSString *b_page_stop2 = [NSString stringWithFormat:#"%d",myPages.b_page_stop];
NSString *b_pag_user_id2 = [NSString stringWithFormat:#"%d",myPages.b_pag_user_id];
NSMutableArray *arrayValue = [[NSMutableArray alloc] initWithObjects:b_pag_id2, b_pag_bo_id2, b_pag_num2, b_pag_note2, b_page_mark2, b_page_stop2, b_pag_user_id2, nil];
NSDictionary *theReqDictionary = [NSDictionary dictionaryWithObjects:arrayValue forKeys:arrayKey];
myArray = [NSMutableArray arrayWithObjects:theReqDictionary,nil];
}
NSLog(#"array size: %d", [myArray count]);
I want to add every element to its key for example
element (b_pag_id2) its key (b_pag_id) ..etc
is this right ?? or how to do this ??
consider that NSLog(#"array size: %d", [myArray count]); gives me 1 and the size of my elements is 14
Before the loop you need to initialize the aray
NSMutableArray *myArray = [NSMutableArray array];
Inside the loop replace following:
myArray = [NSMutableArray arrayWithObjects:theReqDictionary,nil];
with
[myArray addObject:theReqDictionary];
The problem is that you are creating a new array with 1 dictionary in every loop iteration. Instead you need to initialize the array and add values one by one.
Each time through your loop you are creating a new array for myArray that has only one element. You should initialize an empty NSMutableArray before the loop and then simply add your new object to it instead of using arrayWithObjects: to create myArray..
Here i'm giving a short example, and i hope this will help you.
see this code :-
NSMutableArray *arrayValue = [[NSMutableArray alloc]initWithObjects:#"Value1",#"Value2",#"Value3", nil];
NSMutableArray *arrayKey = [[NSMutableArray alloc]initWithObjects:#"1",#"2",#"3", nil];
NSMutableDictionary *dic = [[NSMutableDictionary alloc]init];
for(int i=0;i<3;i++)
{
[dic setObject:[arrayValue objectAtIndex:i] forKey:[arrayKey objectAtIndex:i]];
}
//and you can see this by printing it using nslog-
NSLog(#"%#",[dic valueForKey:#"1"]);
Thank you!!!

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!
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?
You don't say what the error you're seeing is, but you cannot change the values in the NSArray because an NSArray is an immutable container.
Use an NSMutableArray when you want to make modifications. If you have an NSArray already (as in the return value from -componentsSeparatedByString:), you can get a mutable array by doing this:
NSMutableArray * myMutableArray = [NSMutableArray arrayWithArray:lines2];
NSArray is not mutable. First copy it to an NSMutableArray (e.g. using [NSMutableArray arrayWithArray:]) so you can manipulate it.
Didn't you get any warnings during compilation?

how to create an array of string or float in Objective-C

i need some help here, i need to know how to create an array of string retrieved from an array. i'm using powerplot for graph and it only accept float or string array.
i need to create something something like this dynamically.
NSString * sourceData[7] = {#"2", #"1", #"4", #"8", #"14", #"15", #"10"};
Below are my code to find out the numbers in strings.
NSInteger drunked = [appDelegate.drinksOnDayArray count];
NSMutableArray * dayArray = [[NSMutableArray alloc] init];
NSMutableArray * sdArray = [[NSMutableArray alloc] init];
//float *sdArray[7];
for (int i=0; i<drunked; i++) {
DayOfDrinks *drinksOnDay = [appDelegate.drinksOnDayArray objectAtIndex:i];
NSString * dayString= [NSDate stringForDisplayFromDateForChart:drinksOnDay.dateConsumed];
[dayArray addObject:dayString];
NSLog(#"%#",[dayArray objectAtIndex:i]);
drinksOnDay.isDetailViewHydrated = NO;
[drinksOnDay hydrateDetailViewData];
NSString * sdString= [NSString stringWithFormat:#"%#", drinksOnDay.standardDrinks];
[sdArray addObject:sdString];
NSString *tempstring;
NSLog(#"%#",[sdArray objectAtIndex:i]);
}
thanks for the help :)
Array's in Objectice-C aren't that hard to work with:
NSMutableArray *myArray = [NSMutableArray array];
[myArray addObject:#"first string"]; // same with float values
[myArray addObject:#"second string"];
[myArray addObject:#"third string"];
int i;
int count;
for (i = 0, count = [myArray count]; i < count; i = i + 1)
{
NSString *element = [myArray objectAtIndex:i];
NSLog(#"The element at index %d in the array is: %#", i, element); // just replace the %# by %d
}
You can either use NSArray or NSMutableArray - depending on your needs, they offer different functionality.
Following tutorial covers exactly what you are looking after:
http://www.cocoalab.com/?q=node/19
You can also add the elements to the array when you init (and optionally add them later only if you are using the Mutable version of a collection class:
NSMutableArray *myArray = [[NSMutableArray alloc] initWithObjects:#"2", #"1", #"4", #"8", #"14", #"15", #"10", nil];
[myArray addObject:#"22"];
[myArray addObject:#"50"];
//do something
[myArray release];
You can use malloc to create a C-style array. something like this should work:
NSString **array = malloc(numElements * sizeof(NSString *))
some code here
free(array)
Be aware that unlike NSMutable array, c arrays won't do a retain, so you have to manage it if needed. And don't forget the free

Problem with arrays (add and copy)

I've got a problem. I'm trying to sort the items from 1 array (name: mps) into an other array (name: totalArray), but every item should be in a new array. In short: the items in mps should move into a new array, but every item should be in a new array, so the totalArray is an array of arrays. After that, totalArray should be copied back into mps.
To clarify, here is the code:
NSMutableString *oud = [[NSMutableString alloc] init];
NSMutableString *nieuw = [[NSMutableString alloc] init];
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray removeAllObjects];
NSMutableArray *totalArray = [[NSMutableArray alloc] init];
[totalArray removeAllObjects];
tempArray = [[NSMutableArray alloc] init];
[tempArray removeAllObjects];
for (int j = 0; j < [mps count]; j++)
{
nieuw = [[mps objectAtIndex:j] valueForKey:#"ConfigurationAlias"];
if (j != 0)
{
if ([oud rangeOfString:nieuw].location == NSNotFound)
{
NSLog(#"ADDED!");
[totalArray addObjectsFromArray:tempArray];
[oud setString:nieuw];
[tempArray removeAllObjects];
[tempArray addObject:[mps objectAtIndex:j]];
}
else
{
[tempArray addObject:[mps objectAtIndex:j]];
}
}
else {
[oud setString:nieuw];
[tempArray addObject:[mps objectAtIndex:j]];
}
}
//En de array weer laden in de tabel
//NSLog(#"%#", totalArray);
NSLog(#"%i", [mps count]);
[mps removeAllObjects];
NSLog(#"REMOVED!!!");
NSLog(#"%i", [mps count]);
[mps addObjectsFromArray:totalArray];
NSLog(#"Added totalArray: %i", [totalArray count]);
NSLog(#"%i", [mps count]);
[tempArray release];
[totalArray release];
[tabelView reloadData];
}
Now, here comes my problem:
The log gives the line 2011-04-07 10:02:46.368 Fleet Manager[901:40b] ADDED! 11 times, then it posts 16 (mps count, this is correct), then the line REMOVED!, then 0 (mps count, also correct), but then the line: Added totalArray: 15. This can't be correct, it added 11 times but it counts 15?
This a problem for me, in the first place because it's plain incorrect, but the tableview gets screwed up as well because of the section-amount not being correct either (15 sections). Anybody has any idea what's going on?
EDIT: all the objects in mps are dictionaries, and all of them have a value for the key "ConfigurationAlias".
First, I would like to suggest using debugging mode instead of bunch of NSLog functions to track down what's actually happening inside your objects and variables. Try using breakpoints. Set one for [totalArray addObjectsFromArray:tempArray]; line so every time this line of code is reached the execution would stop and let you look around, check different fields' states inside totalArray and tempArray objects.
Concerning your problem... Since you are using addObjectsFromArray: that means that passed array may pass not one but several objects (thus the plural in method name). I guess one of those "11 times" added more than one element - that should explain the actual count being more than the times you've called this method. Again, please check tempArray contents.
Good luck!
If you want to end up with an array of arrays, you need to be allocating temp arrays inside the loop. It also seems like you are overdoing it with clearing out the arrays.
It appears you are trying to add the value from mps to totalArray regardless of the conditions, so it would make sense to only do that in one place (outside of the conditions).
Also, if you are not mutating the arrays (such as tempArray), you can use NSArray instead, which should be smaller and faster.
Finally, you should be able to assign the new array to mps instead of doing the expensive array copying. Not sure if that is somehow referenced as the table delegate, though.
I would try something like:
NSMutableString *oud = [[NSMutableString alloc] init];
NSMutableString *nieuw = [[NSMutableString alloc] init];
NSMutableArray *tempArray;
NSMutableArray *totalArray = [[NSMutableArray alloc] init];
for (int j = 0; j < [mps count]; j++)
{
tempArray = [[NSMutableArray alloc] init];
[totalArray addObject:tempArray];
[tempArray release];
nieuw = [[mps objectAtIndex:j] valueForKey:#"ConfigurationAlias"];
if (j != 0)
{
if ([oud rangeOfString:nieuw].location == NSNotFound)
{
NSLog(#"ADDED!");
[oud setString:nieuw];
}
}
else {
[oud setString:nieuw];
}
}
NSLog(#"%i", [mps count]);
[mps removeAllObjects];
NSLog(#"REMOVED!!!");
NSLog(#"%i", [mps count]);
[mps addObjectsFromArray:totalArray];
NSLog(#"Added totalArray: %i", [totalArray count]);
NSLog(#"%i", [mps count]);
[totalArray release];
[tabelView reloadData];
}
You should
sort the base array in a tempArray
create an empty resultArray
iterate through tempArray and for each item create an itemArray containing the item on the first position and add this array to resutArray
don't forget to release all alloc-ed temporary data
Check this out for sorting easily: Sorting arrays via Apple

How to include a C array in -description

I'm trying to include the elements of an array in the NSString that's returned by the -description method in my class. No clue how to do this in Objective-C...in Java there's string concatenation or StringBuilder, what's the equivalent in Obj-C?
TIA..
Just use NSArray's componentsJoinedByString: method with whatever you want between them as the argument.
NSString *elementsSquishedTogether = [myArray componentsJoinedByString:#""];
NSString *connectedByACommaAndSpace = [myArray componentsJoinedByString:#", "];
If you have a C array, you can turn it into an NSArray with NSArray *converted = [NSArray arrayWithObjects:yourCArray count:yourArrayCount].
The title of your thread talks about C arrays, so here's a modification of jsumners' answer that will deal wiith C arrays.
myArray is assumed to be an ivar declared thusly:
int* myArray;
storage for myArray is assumed to be malloc'd at some point and the size of it is in an ivar declared:
int myArraySize;
The code for description goes something like
- (NSString *)description
{
NSMutableString *returnString = [[[NSMutableString alloc] init] autorelease];
for (int i = 0 ; i < myArraySize ; i++)
{
if (i > 0)
{
[returnString appendString: #", "];
}
[returnString appendFormat: #"%d", myArray[i]];
}
return [NSString stringWithFormat: #"[%#]", returnString];
}
There are variations. The above version formats the string with bracket delimiters and commas between elements. Also, it returns an NSString instead of an NSMutableString which is not a big deal, but I feel that if you say you are returning an immutable object, you probably should.
The following could should "build" a string representation of your array. Notice that it is using the -description method of the objects in the array. If you want something different you will have to make the necessary change.
- (NSString *)description: (id) myArr {
NSMutableString *returnString = [[[NSMutableString alloc] init] autorelease];
for (int i = 0, j = [myaArr count]; i < j; i++) {
[returnString appendString: [[myArr objectAtIndex: i] description]];
}
return [NSString stringWithString: returnString];
}
Edit:
As JeremyP said, I answered this using Objective-C arrays. I guess I just forgot the question when I started writing my code. I'm going to leave my answer as an alternative way to do it, though. I've also fixed the return string type from a mutable string to an immutable string (as it should be).