this code works fine until I start scrolling:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
Route *r = [data routeForDay:day index:indexPath.row];
cell.textLabel.text = r.name;
cell.imageView.image = r.image;
return cell;
}
It works perfectly for every row until I scroll down, when it crashes with objc_msgsend on cell.imageView.image = r.image; I’ve confirmed that nothing is nil, I’ve even checked the retainCount for everything involved. I’m completely at a loss, any ideas? Thanks.
Edit:
I solved the problem, but do not understand how the change in code makes the bug go away, so I’d appreciate a hint if anyone knows.
This is how the image was initially created, in the Route init method. image became deallocated when the table was scrolled, in my tableview controller.
NSString *imagePath = [[NSBundle mainBundle] pathForResource:[dict valueForKey:@"image"] ofType:@"png"];
image = [UIImage imageWithContentsOfFile:imagePath];
When I changed the second line to
image = [[UIImage alloc] initWithContentsOfFile:imagePath];
it worked fine.
I’m just a little confused and unhappy.
Your bug is most definitely a retain/release problem. Try to turn on zombies. If you don’t know how to do that, see below and read this tech note.
I assume one of the objects pointed to by
data,r, orr.imageis not retained properly.One more thing: don’t look at
retainCountbefore understanding memory management (and especially autorelease pools) in depth. Otherwise you’ll only be confused by the returned value.How to enable zombies:
Edit:
Congratulations on finding the bug. The only pice of the puzzle you’re still missing is understanding Cocoa’s memory management. I recommend that you read the official documentation, as it is concise and easy to read.
In short:
imageWithContentsOfFile:returns an autoreleased object, whileinitWithContentsOfFile:returns a retained object. But again: read the docs, or you’ll continue having memory errors.