spen123
spen123

Reputation: 3524

NSMutableArray adds same NSDictionary multiple times

I am looping through an array, getting two items and putting them in a dictionary, and then add them to an array, but it keeps adding the last item of the array for the number objects in the array, even though when I log the dictionary inside the loop it has the correct value. Here is my code

            for (TFHppleElement *element in nodesArray) {

    [nameAndHrefDict setObject:[element objectForKey:@"href"] forKey:@"href"];
    [nameAndHrefDict setObject:[element text] forKey:@"name"];
    NSLog(@"PRE: %@", nameAndHrefDict);
    [arrayOfDicts addObject:nameAndHrefDict];
    NSLog(@"IN: %@", arrayOfDicts);


}

In the log I see this

PRE: {
href = "/dining-choices/res/index.html";
name = "Commons Dining Hall";
}

IN: (
    {
    href = "/dining-choices/res/index.html";
    name = "Commons Dining Hall";
}
PRE: {
href = "/dining-choices/res/sage.html";
name = "Russell Sage Dining Hall";
}

IN: (
    {
    href = "/dining-choices/res/sage.html";
    name = "Russell Sage Dining Hall";
},
    {
    href = "/dining-choices/res/sage.html";
    name = "Russell Sage Dining Hall";
}
)

What is happening?

But it add the last value of nodesArray 8 times, instead of each value, why?

Thanks for the help in advance.

Upvotes: 0

Views: 431

Answers (4)

Niraj Paul
Niraj Paul

Reputation: 1538

You have to instantiate the dictionary in the loop : see the code

NSMutableArray *saveData = [[NSMutableArray alloc]init];

for (int i=0; i<records.count; i++) {

    RecordTable *record = [records objectAtIndex:i];
    NSString *addID = record.addr_id;

    NSMutableDictionary *saveToDic = [[NSMutableDictionary alloc]init];
    [saveToDic setValue:addID forKey:@"addr_id"];

    [saveData addObject:saveToDic];

    }

Upvotes: 0

james brown
james brown

Reputation: 250

You need to alloc and init the array each time, so that there is new memory for it and then it wont add the same array 8 times

Upvotes: 0

Tommy
Tommy

Reputation: 100622

Objects are added to arrays by reference. The array doesn't create a copy of the dictionary, it just keeps a record of which dictionary has been added. You're adding the same dictionary, nameAndHrefDict, to the array every time. So the array considers itself to hold the same object multiple times.

At each iteration you are changing the value of that object but it is still the same object.

So the underlying issue is identify versus value. An array is populated by identity. You're expecting it to populate by value.

To fix: copy the dictionary when you add it to the array, or just create a brand new dictionary from scratch each time.

Upvotes: 1

aobs
aobs

Reputation: 1103

Please try:

 for (TFHppleElement *element in nodesArray) {

      [arrayOfDicts addObject:[NSDictionary dictionaryWithObjectsAndKeys:[element objectForKey:@"href"], @"href", [element text], @"name", nil]];
 }

Upvotes: 1

Related Questions