Reputation: 1644
Using:
Have 1 image and text on every cell. Images are not getting resized while scrolling. Have two versions of images image.png and [email protected].
The custom cell was managed by drugging UIImageView and UILabel in storyboard.
Code:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
Continent *continent=[self.items objectAtIndex:[indexPath row]];
ContinentCell *cell = (ContinentCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
cell.continentName.text=continent.continentName;
cell.textView.text=continent.countriesHash;
cell.imageView.image=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];
return cell;
}
Where's the evil? Thank you in advance.
Upvotes: 2
Views: 5615
Reputation: 473
Check out Polishing your App: Tips and Tricks to Improve Responsiveness and Performance video of WWDC 2011 from 26:48. They have discussed exactly about the problem you are facing. Don't miss out, it would be really helpful..!
Upvotes: 5
Reputation: 3401
- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
Continent *continent=[self.items objectAtIndex:[indexPath row]];
ContinentCell *cell = (ContinentCell*)[tableView
dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[ContinentCell alloc]
initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
}
cell.continentName.text=continent.continentName;
cell.textView.text=continent.countriesHash;
//cell.imageView.image=[UIImage imageWithContentsOfFile:[[NSBundle mainBundle]
pathForResource:continent.continentImage ofType:@"png"]];
cell.imageView.image = [UIImage cachedImage:continent.continentImage];
return cell;
}
I will recommend you to use imageNamed instead of imageWithContentsOfFile.
imageNamed method loads the image in cache and next time it will load from cache, where as imageWithContentsOfFile method loads the image from your specified path without NO
cahching and it will create multiple copy in memory.
You can create your own image cache method. Just declare NSMutableDictionary *imagedCacheDict
If you run out of memory you can remove all the objects by [imagedCacheDict removeAllObjects]
- (UIImage*)cachedImage:(NSString*)fileName
{
UIImage *cacheImage = [imagedCacheDict objectForKey:fileName];
if (nil == cacheImage)
{
NSString *cacheImageFile = [NSString stringWithFormat:@"%@.png",
[[NSBundle mainBundle] resourcePath], fileName];
cacheImage = [UIImage imageWithContentsOfFile:cacheImageFile];
[imagedCacheDict setObject:cacheImage forKey:fileName];
}
return cacheImage;
}
So, never use the imageNamed method, it will bring out your application by consuming lot of memory.
Upvotes: 2
Reputation: 45180
Make sure that your images are not big and then:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
Continent *continent=[self.items objectAtIndex:[indexPath row]];
ContinentCell *cell = (ContinentCell*)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(cell == nil) cell = [[ContinentCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier]
cell.continentName.text = continent.continentName;
cell.textView.text = continent.countriesHash;
cell.imageView.image = [UIImage imageNamed:continent.continentImage];
return cell;
}
I made 2 significant changes:
Added if(cell == nil) [[ContinentCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier]
, because I didn't find the code for initializing cell (unless you use -registerNib
or the other super-sectet function, which I can't say because it's under NDA)
Replaced imageWithContentsOfFile:...
with simple imageNamed
, because you load the image from your main bundle and, if image is not big, -imageNamed
caches it, so it loads quicker. (and -imageNamed doesn't need the file extension)
Upvotes: 2
Reputation: 2150
[UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];
Is expensive. You want to load the image the image asynchronously in the background then present it on the main thread when ready.
Here's a very rough solution
cell.imageView.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
UIImage * img = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:continent.continentImage ofType:@"png"]];
dispatch_sync(dispatch_get_main_queue(), ^{
cell.imageView.image = img;
});
});
Upvotes: 12