Reputation: 2527
I have a table view cell with two image views, one image view is a placeholder, and on top of the other image is the actual image I load from the documents directory. I am having issues with the image being incorrectly displayed when the table view resuses the cell.
I solved my problem by using the below method in the cell class, but I have read that this can cause performance issues, any ideas on a better solution?
- (void)prepareForReuse
{
[[self imageView] setImage:nil];
}
Upvotes: 1
Views: 701
Reputation: 90117
First of all, you are not calling [super prepareForReuse]
like you should.
And the documentation is pretty clear, you should be setting the image in tableView:cellForRowAtIndexPath:
because it's content.
If you set the image in tableView:cellForRowAtIndexPath:
there is no point to set it to nil in prepareForReuse
.
Imagine the following flow.
prepareForReuse
sets imageView.image to niltableView:cellForRowAtIndexPath:
dequeues the cell and sets imageView.image to image1You are setting imageView.image twice.
If you use nil there might be no measurable performance impact at all. But you might come to the idea to actually set a placeHolder image. So the cell is queued and prepared for reuse, you set the placeholder image; later the cell is dequeued and the placeholder image is replaced by a real image before the placeholder image was even visible.
I would remove the prepareForReuse
method completely. You don't need it if you set the image in tableView:cellForRowAtIndexPath:
from the documentation:
If a UITableViewCell object is reusable—that is, it has a reuse identifier—this method is invoked just before the object is returned from the UITableView method dequeueReusableCellWithIdentifier:. For performance reasons, you should only reset attributes of the cell that are not related to content, for example, alpha, editing, and selection state. The table view's delegate in tableView:cellForRowAtIndexPath: should always reset all content when reusing a cell. If the cell object does not have an associated reuse identifier, this method is not called. If you override this method, you must be sure to invoke the superclass implementation.
Upvotes: 2
Reputation: 9040
Since you have a placeholder image behind this image view, There is nothing wrong if you set the top imageview's image to nil.
To enhance the image generating process, you can use a NSCache object like this,
1)
@property(nonatomic, strong) NSCache *imageCache;
2) Call this methods inside tableView cellForRowAtIndexPath: method, the image generating process can be moved into this,
-(UIImage *) imageForIndexPathRow:(int) row{
id image = [self.imageCache objectForKey:[NSNumber numberWithInt:row]];
if(!image){//if the image is not in the cache,
UIImage *newImage; //create image here
[self.imageCache setObject:newImage forKey:[NSNumber numberWithInt:row]];
return newImage;
}
return (UIImage *) image;
}
Upvotes: 0