Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>The best way I found of solving this problem was by keeping my own cache of images, and pre-warming it on viewWillAppear on a background thread, like so:</p> <pre><code>- (void) warmThubnailCache { if (self.isWarmingThumbCache) { return; } if ([NSThread isMainThread]) { // do it on a background thread [NSThread detachNewThreadSelector:@selector(warmThubnailCache) toTarget:self withObject:nil]; } else { self.isWarmingThumbCache = YES; NIImageMemoryCache *thumbCache = self.thumbnailImageCache; for (GalleryImage *galleryImage in _galleryImages) { NSString *cacheKey = galleryImage.thumbImageName; UIImage *thumbnail = [thumbCache objectWithName:cacheKey]; if (thumbnail == nil) { // populate cache thumbnail = [UIImage imageWithContentsOfFile:galleryImage.thumbImageName]; [thumbCache storeObject:thumbnail withName:cacheKey]; } } self.isWarmingThumbCache = NO; } } </code></pre> <p>You can also use GCD instead of NSThread, but I opted for NSThread, since only one of these should run at a time, so no queue is necessary. Also, if you have an essentially limitless number of images, you will have to be more careful than I. You will have to be more clever about loading the images around a user's scroll location, rather than all of them, like I do here. I can do this because the number of images, for me, is fixed.</p> <p>I should also add that your collectionView:cellForItemAtIndexPath: should use your cache, like so: </p> <pre><code>- (PSUICollectionViewCell *)collectionView:(PSUICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"GalleryCell"; GalleryCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:CellIdentifier forIndexPath:indexPath]; GalleryImage *galleryImage = [_galleryManager.galleryImages objectAtIndex:indexPath.row]; // use cached images first NIImageMemoryCache *thumbCache = self.galleryManager.thumbnailImageCache; NSString *cacheKey = galleryImage.thumbImageName; UIImage *thumbnail = [thumbCache objectWithName:cacheKey]; if (thumbnail != nil) { cell.imageView.image = thumbnail; } else { UIImage *image = [UIImage imageWithContentsOfFile:galleryImage.thumbImageName]; cell.imageView.image = image; // store image in cache [thumbCache storeObject:image withName:cacheKey]; } return cell; } </code></pre> <p>Make sure your cache clears when you get a memory warning, or use something like NSCache. I'm using a framework called Nimbus, which has something called NIImageMemoryCache, which lets me set a max number of pixels to cache. Quite handy.</p> <p>Other than that, one gotcha to take note is is to NOT use UIImage's "imageNamed" method, which does it's own caching, and will give you memory problems. Use "imageWithContentsOfFile" instead.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload