title: How to Asynchronously load UITableViewcell images so that scrolling doesn't lag
body: <p>I've tried using <a href="https://github.com/nicklockwood/AsyncImageView" rel="nofollow">ASyncImageView</a> for this purpose, but I'm a bit confused as to how I'd implement it for my specific case. I currently have a <code>MatchCenterViewController</code> that contains a table inside of it. It's loading the images for the cells synchronously, which is causing a lot of lag when scrolling through the table. How can I modify the way I'm loading the remote images so that it's done asynchronously? My code is below: </p>
  
  <pre><code>#import "MatchCenterViewController.h"
  #import &lt;UIKit/UIKit.h&gt;
  #import "MatchCenterCell.h"
  
  @interface MatchCenterViewController () &lt;UITableViewDataSource, UITableViewDelegate&gt;
  
  @property (nonatomic, strong) UITableView *matchCenter;
  @property (nonatomic, assign) BOOL matchCenterDone;
  @property (nonatomic, assign) BOOL hasPressedShowMoreButton;
  
  @end
  
  
  
  @implementation MatchCenterViewController
  
  
  - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
  {
      self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
      if (self) {
      }
      return self;
  }
  
  
  - (void)viewDidLoad
  {
      [super viewDidLoad];
  
      _matchCenterDone = NO;
      _hasPressedShowMoreButton = NO;
  
      // Set up MatchCenter table
      self.matchCenter = [[UITableView alloc] initWithFrame:self.view.bounds style:UITableViewCellStyleSubtitle];
      self.matchCenter.frame = CGRectMake(0,70,320,self.view.frame.size.height-100);
      self.edgesForExtendedLayout = UIRectEdgeAll;
      self.matchCenter.contentInset = UIEdgeInsetsMake(0.0f, 0.0f, CGRectGetHeight(self.tabBarController.tabBar.frame), 0.0f);
      _matchCenter.dataSource = self;
      _matchCenter.delegate = self;
      [self.view addSubview:self.matchCenter];
  
      self.expandedSection = -1;
  
      _matchCenterArray = [[NSArray alloc] init];
  
      // Refresh button
      UIImageView *refreshImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"refresh.png"]];
      refreshImageView.frame = CGRectMake(280, 30, 30, 30);
      refreshImageView.userInteractionEnabled = YES;
      UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(refreshPressed:)];
      [refreshImageView addGestureRecognizer:tapGesture];
      [self.view addSubview:refreshImageView];
  
  
      // Preparing for MC and indicating loading
      self.matchCenterArray = [[NSArray alloc] init];
  
      UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
      activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
      [self.view addSubview: activityIndicator];
  
      [activityIndicator startAnimating];
  
      _matchCenterDone = NO;
  
      // Disable ability to scroll until table is MatchCenter table is done loading
      self.matchCenter.scrollEnabled = NO;
  
      [PFCloud callFunctionInBackground:@"MatchCenter3"
                         withParameters:@{}
                                  block:^(NSArray *result, NSError *error) {
  
                                      if (!error) {
                                          _matchCenterArray = result;
  
                                          [activityIndicator stopAnimating];
  
                                          [_matchCenter reloadData];
  
                                          _matchCenterDone = YES;
                                          self.matchCenter.scrollEnabled = YES;
                                          NSLog(@"Result: '%@'", result);
                                      }
                                  }];
  
  }
  
  - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
  {
      return _matchCenterArray.count;
  }
  
  //the part where i setup sections and the deleting of said sections
  
  - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
      return 21.0f;
  }
  
  - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
  {
      return 40;
  }
  
  - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
  //code snipped out for conciseness
  }
  
  - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  //Header code snipped out for conciseness
  }
  
  - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
  {
      NSDictionary *currentSectionDictionary = _matchCenterArray[section];
      NSArray *top3ArrayForSection = currentSectionDictionary[@"Top 3"];
  
      return (top3ArrayForSection.count-1 &lt; 1) ? 1 : top3ArrayForSection.count-1;
  }
  
  // Cell layout
  - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
      // Initialize cell
      static NSString *CellIdentifier = @"MatchCenterCell";
      MatchCenterCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
      if (!cell) {
          // if no cell could be dequeued create a new one
          cell = [[MatchCenterCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
      }
  
      //[cell.contentView addSubview:cell.priceLabel];
      [cell.contentView addSubview:cell.conditionLabel];
  
      // No cell seperators = clean design
      tableView.separatorColor = [UIColor clearColor];
  
      NSDictionary *currentSectionDictionary = _matchCenterArray[indexPath.section];
      NSArray *top3ArrayForSection = currentSectionDictionary[@"Top 3"];
  
      if (top3ArrayForSection.count-1 &lt; 1) {
  
          // title of the item
          cell.textLabel.text = @"No items found, but we'll keep a lookout for you!";
          cell.textLabel.font = [UIFont systemFontOfSize:12];
  
      }
  
      else {
  
          // title of the item
          cell.textLabel.text = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Title"];
          cell.textLabel.font = [UIFont systemFontOfSize:14];
  
          // price + condition of the item
          NSString *price = [NSString stringWithFormat:@"$%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Price"]];
          NSString *condition = [NSString stringWithFormat:@"%@", _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Item Condition"]];
  
          cell.detailTextLabel.text = [NSString stringWithFormat:@"%@ - %@", price, condition];
          cell.detailTextLabel.textColor = [UIColor colorWithRed:0/255.0f green:127/255.0f blue:31/255.0f alpha:1.0f];
  
          // image of the item
          NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Image URL"]]];
          [[cell imageView] setImage:[UIImage imageWithData:imageData]];
  
          cell.imageView.layer.masksToBounds = YES;
          cell.imageView.layer.cornerRadius = 2.5;
  
      }
  
      return cell;
  }
  
  
  - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
      if (indexPath.section == self.expandedSection || indexPath.row &lt;= 3) {
          return 65;
      }
      return 0;
  }
  
  - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
  {
      if (_matchCenterDone == YES) {
          self.itemURL = _matchCenterArray[indexPath.section][@"Top 3"][indexPath.row+1][@"Item URL"];
          [self performSegueWithIdentifier:@"WebViewSegue" sender:self];
      }
  } 
  
  @end
  
  @implementation MoreButton
  @end
  </code></pre>