Reputation: 2818
I'm parsing through an NSDictionary
of json-encoded events and placing them into a two-dimensional NSMutableArray
based on their month -- for display in a sectioned table view.
Since I am adding items to an array and then placing that array in an array (event_container
) in a loop, event_container
shows the correct number of arrays, however, they all appear to be duplicates of the last iteration, so all of the contents of event_container
are the same array.
I believe this is because it's a pointer and/or not being released. I'm unsure of an appropriate way around this or possibly even a better solution. I'm using ARC.
int month = 0;
int current_month = 0;
int counter = 0;
event_container = [[NSMutableArray alloc] init];
temp_array = [[NSMutableArray alloc] init];
for (NSDictionary *result in results)
{
NCEvent *anEvent = [[NCEvent alloc] init];
anEvent.title = [result objectForKey:@"title"];
anEvent.startdate = [result objectForKey:@"startdate"];
anEvent.enddate = [result objectForKey:@"enddate"];
NSDateFormatter *importDate = [[NSDateFormatter alloc] init];
[importDate setDateFormat:@"yyyy-M-d H:m:ss"];
anEvent.dateStart = [importDate dateFromString:anEvent.startdate];
anEvent.dateEnd = [importDate dateFromString: anEvent.enddate];
NSDateFormatter *exportDate = [[NSDateFormatter alloc] init];
[exportDate setDateFormat:@"d"];
anEvent.text_date = [exportDate stringFromDate: anEvent.dateStart];
NSDateFormatter *exportMon = [[NSDateFormatter alloc] init];
[exportMon setDateFormat:@"MMM"];
anEvent.text_mon = [exportMon stringFromDate: anEvent.dateStart];
NSDateFormatter *monthInt = [[NSDateFormatter alloc] init];
[monthInt setDateFormat:@"M"];
month = [[monthInt stringFromDate: anEvent.dateStart] intValue];
if(counter == 1){ //first month
current_month = month;
NSLog(@"I'm the first month: %i", month);
[temp_array addObject:anEvent];
}
else if(month > current_month){ //new month
NSLog(@"This is a new month");
current_month = month;
//add the events array to events container and reset the events array
[self.event_container addObject: temp_array];
[temp_array removeAllObjects];
[temp_array addObject:anEvent];
}
else{
NSLog(@"Same Month"); //same month
[temp_array addObject:anEvent];
}
NSLog(@"Event month integer: %i", month);
anEvent = nil;
counter++;
}
Those arrays are declared as properties:
@property (nonatomic, retain) NSMutableArray *event_container;
@property (nonatomic, retain) NSMutableArray *temp_array;
Upvotes: 0
Views: 176
Reputation: 64002
Your suspicions about the array being a pointer is basically correct. The problem is that your temp_array
isn't so temporary -- it's in fact the same array object every time through your loop.
You're creating it outside the loop, and whenever you send it addObject:
or removeAllObjects
, it's affecting the stuff that you've already put in there.
The key part, though, is that when you add the temp_array
to event_container
, it's the exact same object. It's not copied; the event_container
array just gets a pointer to temp_array
. When you add it again, it's the same thing. Since event_container
just holds a whole bunch of pointers, you end up looking at the same object when you inspect it.
That's what's happening. To solve this, you need to create a separate array for each month; I think that sch's answer will work for you.
A quick demonstration:
NSMutableArray * container = [NSMutableArray array];
NSMutableArray * temp = [NSMutableArray array];
int i;
for( i = 0; i < 5; i++ ){
[temp addObject:[NSNumber numberWithInt:i]];
[container addObject:temp]; // Doesn't copy; just adds pointer to temp
[temp removeAllObjects];
}
// Inspecting container now, we find that it has five arrays, all empty.
NSLog(@"%@", container);
Upvotes: 1
Reputation: 27516
In the line:
[self.event_container addObject: temp_array];
You are always adding the same instance temp_array
to self.event_container
. This is why you see the same array duplicated many times.
You can solve this by doing the following for example:
-Add the following before your for loop
for (int i = 0; i < 12; i++) {
[event_container addObject:[NSMutableArray array]];
}
for (NSDictionary *result in results)
...
-Remove
if(counter == 1){ //first month
current_month = month;
NSLog(@"I'm the first month: %i", month);
[temp_array addObject:anEvent];
}
-and change the code that comes after that into :
tmp_array = [event_container objectAtIndex:month];
[temp_array addObject:anEvent];
Upvotes: 2
Reputation: 7655
temp_array is a pointer type (like all objects in objective c). Therefore, with this call:
[self.event_container addObject: temp_array];
...you are adding a pointer to that object to event_container. You are not creating a new array, merely adding multiple pointers to the same object. What you most likely want to do is add a (pointer to a) copy of the object, like this:
[self.event_container addObject: [temp_array mutableCopy]];
Upvotes: 0