title: Best way to cache images on ios app?
body: <p>Shortly, I have an <code>NSDictionary</code> with urls for images that I need to show in my <code>UITableView</code>. Each cell has a title and an image. I had successfully made this happen, although the scrolling was lagging, as it seemed like the cells downloaded their image every time they came into the screen.
  I searched for a bit, and found <code>SDWebImage</code> on github. This made the scroll-lagg go away. I am not completely sure what it did, but I believed it did some caching. 
  But! Every time I open the app for the first time, I see NO images, and I have to scroll down, and back up for them to arrive. And if I exit the app with home-button, and open again, then it seemes like the caching is working, because the images on the screen are visible, however, if I scroll one cell down, then the next cell has no image. Until i scroll past it and back up, or if I click on it. Is this how caching is supposed to work? Or what is the best way to cache images downloaded from the web? The images are being updated rarily, so I was close to just import them to the project, but I like to have the possibility to update images without uploading an update..</p>
  
  <p>Is it impossible to load all the images for the whole tableview form the cache(given that there is something in the cache) at launch? Is that why I sometimes see cells without images?</p>
  
  <p>And yes, I'm having a hard time understanding what cache is.</p>
  
  <p><strong>--EDIT--</strong></p>
  
  <p>I tried this with only images of the same size (500x150), and the aspect-error is gone, however when I scroll up or down, there are images on all cells, but at first they are wrong. After the cell has been in the view for some milliseconds, the right image appears. This is amazingly annoying, but maybe how it has to be?.. It seemes like it chooses the wrong index from the cache at first. If I scroll slow, then I can see the images blink from wrong image to the correct one. If I scroll fast, then I believe the wrong images are visible at all times, but I can't tell due to the fast scrolling. When the fast scrolling slows down and eventually stops, the wrong images still appear, but immediately after it stops scrolling, it updates to the right images. I also have a custom <code>UITableViewCell</code> class, but I haven't made any big changes.. I haven't gone through my code very much yet, but I can't think of what may be wrong.. Maybe I have something in the wrong order.. I have programmed much in java, c#, php etc, but I'm having a hard time understanding Objective-c, with all the <code>.h</code> and <code>.m</code> ...
  I have also `</p>
  
  <pre><code>@interface FirstViewController : UITableViewController{
  
  /**/
  NSCache *_imageCache;
  }
  </code></pre>
  
  <p>(among other variables) in <code>FirstViewController.h</code>. Is this not correct?</p>
  
  <p>Here's my <code>cellForRowAtIndexPath</code>.</p>
  
  <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
  {
  static NSString *CellIdentifier = @"hallo";
  CustomCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
  
  if (cell == nil)
  {
      cell = [[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
  }
  
  NSMutableArray *marr = [hallo objectAtIndex:indexPath.section];
  NSDictionary *dict = [marr objectAtIndex:indexPath.row];
  
  NSString* imageName = [dict objectForKey:@"Image"];
  //NSLog(@"url: %@", imageURL);
  
  UIImage *image = [_imageCache objectForKey:imageName];
  
  if(image)
  {
      cell.imageView.image = image;
  }
  else
  {
      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
  
          NSString* imageURLString = [NSString stringWithFormat:@"example.com/%@", imageName];
          NSURL *imageURL = [NSURL URLWithString:imageURLString];
          UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:imageURL]];
  
          if(image)
          {
              dispatch_async(dispatch_get_main_queue(), ^{
                  CustomCell *cell =(CustomCell*)[self.tableView cellForRowAtIndexPath:indexPath];
                  if(cell)
                  {
                      cell.imageView.image = image;
                  }
              });
              [_imageCache setObject:image forKey:imageName];
          }
      });
  }
  
  cell.textLabel.text = [dict objectForKey:@"Name"];
  
  return cell;
  }
  </code></pre>