I hope someone understands what happens to my NSMutableArray.
I read records a, b, c, d from a database, load the fields into an object an add the object to an array. To do this I read the records into an instance of that object (tmpEvent) and add the Object to the target array (NSMutableArray myArray).
the code looks like:
for (condition) {
tmpEvent.field1 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 0)];
tmpEvent.field2 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 1)];
tmpEvent.field3 = [NSString stringWithUTF8String:(char*)sqlite3_column_text(stmt, 2)];
NSLog(@"myArray: adding %@", tmpEvent.field1);
[myArray addObject:tmpEvent];
}
The NSLog shows
myArray: adding a
myArray: adding b
myArray: adding c
myArray: adding d
Subsequent I enumerate the array (this can be in the same or a different method):
for (myObject *records in myArray) {
NSLog(@"iEvents value %@", records.field1);
}
The NSLog now shows:
myArray value d
myArray value d
myArray value d
myArray value d
a mystery …. ??? any thoughts?
You need to allocate a new “iEvent” for each event. tmpEvent.field1 is pointing to the same place in memory for each subsequent add, therefore you are modifying the object that is already stored in the array. NSArray does not make a new copy of the object, just stores its pointer/address.
One fix:
[myArray addObject:[tmpEvent copy]];
This assumes the members of the iEvent class conform to NSCopy.
Another is to allocate a new tmpEvent for each event that you want to store.
Question: But does this mean that when I free my array agein I need to enumerate through and “manually” release the objects again?
Answer: You should send the object a release after adding it to the array as the array sends it a retain. When you dispose of the array, all objects are sent a release so you don’t have to. See below…
Give the alloc option a try as conforming to NSCopying requires you to alloc an object anyway:
for (condition) {
tmpEvent = [[TmpEvent alloc] init]; // Or however it is initialized
// NSArray retains objects that you add.
[tmpEvent release];
}
—- To Conform to NSCopy —
1. Class must inherit from NSCopying
@interface TmpEvent : NSObject …
Implement – (id) copyWithZone:(NSZone *) zone
TmpEvent *copyOfMyself = [[TmpEvent alloc] init];
copyOfMyself.field1 = [self.field1 copy];
…. etc.
return copyOfMyself;
}