Reputation: 690
Xcode 4.2 iPhone Project
I am trying to create a tableView that's populated from an NSMutableArray. Currently when I run the simulator the tableView in question shows 5 rows (this is correct) but all rows have the same string (this obviously is not correct). The string being shown is from the LAST object defined in my NSMutableArray. Here's the code:
- (void)viewDidLoad
{
[super viewDidLoad];
codes = [[NSMutableArray alloc] init];
TableList *listItem = [[TableList alloc] init];
[listItem setCodeTitle:@"Test Name 1"];
[listItem setCodeNumber:@"101"];
[listItem setCodeDescription:@"This is the description for 101."];
[codes addObject:listItem];
[listItem setCodeTitle:@"Test Name 2"];
[listItem setCodeNumber:@"102"];
[listItem setCodeDescription:@"This is the description for 102."];
[codes addObject:listItem];
[listItem setCodeTitle:@"Test Name 3"];
[listItem setCodeNumber:@"103"];
[listItem setCodeDescription:@"This is the description for 103."];
[codes addObject:listItem];
[listItem setCodeTitle:@"Test Name 4"];
[listItem setCodeNumber:@"104"];
[listItem setCodeDescription:@"This is the description for 104."];
[codes addObject:listItem];
[listItem setCodeTitle:@"Test Name 5"];
[listItem setCodeNumber:@"105"];
[listItem setCodeDescription:@"This is the description for 105."];
[codes addObject:listItem];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
//#warning Potentially incomplete method implementation.
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
//#warning Incomplete method implementation.
// Return the number of rows in the section.
return [codes count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"CodeCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
// Configure the cell...
TableList *current = [codes objectAtIndex:indexPath.row];
cell.textLabel.text = [current codeTitle];
return cell;
}
I hope this is painfully obvious to anyone with more experience than me... I have very little.
Upvotes: 3
Views: 6033
Reputation: 753
Also, if you are using NSMutableArray, try chaining it to an NSArray.
Upvotes: 0
Reputation: 185681
You're storing the exact same object 5 times into your array. You seem to be under the misapprehension that -addObject:
will copy the object it's handed, but it won't. The simple fix is to change your -addObject:
lines to say
[codes addObject:[[listItem copy] autorelease]];
This is, of course, assuming your TableList
class conforms to <NSCopying>
. If it doesn't, you'll probably want to do so. If you're unwilling to support copying in that class, then you'll have to create a new TableList
object each time.
Also, unless you're using ARC, you're leaking your TableList
object.
In order to support -copy
, you must conform to <NSCopying>
, which is a protocol that declares the method -copyWithZone:
(though the zone argument is a historical curiosity that should be ignored). To do this, modify your @interface
line to look like
@interface TableList : NSObject <NSCopying>
and then implement the method -copyWithZone:
- (id)copyWithZone:(NSZone *)zone {
// If our superclass conformed to <NSCopying> we'd call [super copy]
// But it doesn't, so alloc/init a new instance
TableList *newObj = [[TableList alloc] init];
newObj.codeTitle = self.codeTitle;
newObj.codeNumber = self.codeNumber;
newObj.codeDescription = self.codeDescription;
return newObj;
}
This is just a sample implementation. It assumes that those 3 properties are the only values on the object, and that simply assigning to the property is appropriate. If you have internal ivars that need to be copied over, you can get ivar access by using something like
newObj->ivar = copyIvar(self->ivar); // self->ivar is the same as just plain ivar
Upvotes: 3