title: UITableView with infite scrolling and lazy loading
body: <p>I got an <code>UITableView</code> which is filled with an unknown amount of rows. Each row contains (for example 3) images and the application gathers this information from a webservice.</p>
  
  <p>For the <code>UITableView</code> I implemented infinite scrolling. Whenever the table almost reaches the end of the current amount of rows, I initiate a call to the webservice, to fetch the next 50 rows of data. I do this in the <code>scrollViewDidScroll</code> method which is called by the <code>UITableView</code>.</p>
  
  <pre><code>- (void) scrollViewDidScroll:(UIScrollView *)scrollView
  {
      CGFloat actualPosition = scrollView.contentOffset.y;
  
      float bottomOffset = 450;
      if([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad)
          bottomOffset = 1000;
  
      CGFloat contentHeight = scrollView.contentSize.height - bottomOffset;
      if (actualPosition &gt;= contentHeight &amp;&amp; !_loading &amp;&amp; !_cantLoadMore)
      {
          self.loading = YES;
  
          _currentPage++;
  
          NSMutableDictionary* dict = [[NSMutableDictionary alloc] init];
          [dict setObject:[NSNumber numberWithInt:_currentPage] forKey:@"page"];
          [dict setObject:[_category objectForKey:@"ID"] forKey:@"category"];
  
          [self performSelectorInBackground:@selector(getWallpapersInBackground:) withObject:dict];
      }
  }
  </code></pre>
  
  <p>The images in the rows of the <code>UITableView</code> are lazy loaded. Whenever a row is visible, the images are loaded in a separate thread and the rows are updated once an image is fully downloaded. The principle I use for lazy loading, is the same as Apple suggests in their documentation. The image is also added to a local <code>NSDictionary</code>, so I can fetch it when the row scrolls out of the screen and back in (and the row is recreated).</p>
  
  <p>Because the amount of pictures in a single view can go up to 2000 - 3000, I also cache the images to disk and clear out the images from the <code>NSDictionary</code> when they are further than X rows away. When the user scrolls down and up again the following happens:</p>
  
  <ol>
  <li>New rows are displayed</li>
  <li>Lazy loading method is called, which checks if the image is present on disk or that it should download it.</li>
  <li>When the image is downloaded or fetched from disk, it performs a codeblock, which displays the image in the row. Images downloaded from the internet, are also cached to disk.</li>
  <li><code>UIImage</code> is added to <code>NSDictionary</code> for faster caching of images that need to be within reach.</li>
  <li>Images which are in rows, 15 rows or further from the visible rows are removed from the <code>NSDictionary</code>, because of memory problems (too many <code>UIImage</code> objects in the <code>NSDictionary</code> cause out-of-memory errors).</li>
  </ol>
  
  <p>When the UITableView almost reaches the end, the following occurs:</p>
  
  <ol>
  <li>UITableView almost reaches end of currently loaded rows</li>
  <li>Call to webservice, with loads of new rows (50)</li>
  <li>The new rows are added to an array, which is used for the <code>numberOfItemsInSection</code> method.</li>
  <li>A <code>reloadData</code> is called to make sure the <code>UITableView</code> populates with the extra new rows.</li>
  <li>New rows that contain images, performs the steps mentioned above to lazy load the images.</li>
  </ol>
  
  <p>So, the problem I have is when I am adding new records from the webservice. When I call a <code>reloadData</code> on the <code>UITableView</code> some images are loading from disk again and some hickups occur while scrolling.</p>
  
  <p>I am looking for a solution for this. I tried using <code>insertItemsAtIndexPaths</code> with the amount of new rows, to add them to the <code>UITableView</code>, but this makes my lazy load method already download the images (because somehow all the cells are created at that time, even when they are not visible, checking if cell is visible during creation delivers unexpected results, images not loading, cells look weird, etc).</p>
  
  <p>So, what I essentially am looking for is a solution for an infinite scrolling UITableView, which lazy loads images from the web/disk and is as smooth as the photo application. Since images are all loaded in separate threads, I don't understand why scrolling isn't as smooth as a baby's skin.</p>