Skip to content

Instantly share code, notes, and snippets.

@0xjmp
Last active August 29, 2015 14:00
Show Gist options
  • Select an option

  • Save 0xjmp/11156123 to your computer and use it in GitHub Desktop.

Select an option

Save 0xjmp/11156123 to your computer and use it in GitHub Desktop.
The main issue with this method is that it's performing a task ([NSData dataWithContentsOfURL]) on the main thread and is therefore blocking ui actions (such as scrolling) until it has finished loading the image. A secondary issue is that this method doesn't dequeue sufficiently. Dequeuing is a critical factor in increasing a scroll-based class'…
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MemeCell"];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"MemeCell"];
}
// Dequeue subviews
NSInteger tag = 1415;
UIImageView *imageView = (UIImageView *)[cell viewWithTag:tag];
if (!imageView)
{
imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
imageView.tag = tag;
[cell addSubview:imageView];
}
NSInteger activityTag = 54321;
if (!imageView.image && ![cell viewWithTag:activityTag])
{
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.tag = activityTag;
[cell addSubview:activityIndicator];
activityIndicator.center = cell.center;
[activityIndicator startAnimating];
// No image set... fetch it on a background thread & set it dyanmically (weak reference).
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void)
{
NSURL *url = [NSURL URLWithString:[photo_urls objectAtIndex:indexPath.row]];
NSError *error = nil;
NSData *data = [NSData dataWithContentsOfURL:url options:NSDataReadingMappedIfSafe error:&error];
UIImage *image = [UIImage imageWithData:data];
imageView.image = image;
[activityIndicator stopAnimating];
if (error)
{
/**
* To prevent -dataWithContentsOfUrl from being called on a faulty url again, we're going to
* leave activityIndicator, which will block future attempts (dequeueing) to load the image.
*/
NSLog(@"Error loading image at url (%@) error: %@", url.absoluteString, error);
}
else
{
// Removing activityIndicator from it's superview will reset the cell's -viewWithTag: results.
// The imageView's image is set, we don't need to call -dataWithContentsOfURL: again.
[activityIndicator removeFromSuperview];
}
});
}
return cell;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment