@ggrana has the right idea. Downloading async will definitely help. However, you still do redundant work if you download from a file each time. One thing to consider is to increase async load with NSCache . This is basically an NSDictionary , but memory management itself resets data when there is memory pressure.
So, if you have a memory budget, you can make your thumbnails on the fly (so you donβt need to hardcode the size) and store them in the cache. Thus, your images only appear for the first time. Each time after that they instantly load.
You can use it like this:
@implementation ... { NSCache * _johnny; // get it? } - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { [cell setImage:nil]; // since they are reused, prevents showing an old image dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ UIImage * sticker = [self thumbnailOfSize:CGSizeMake(desiredImageWidth, desiredImageHeight) forIndex:[indexPath row]]; dispatch_async(dispatch_get_main_queue(), ^{ [cell setImage:sticker]; }); }); } // load image from disk and cache thumbnail version - (UIImage*) thumbnailOfSize:(CGSize)size forIndex:(NSInteger)index { NSString * cacheKey = [NSString stringWithFormat:@"%@ %d", NSStringFromCGSize(size), index]; UIImage * image = [_johnny objectForKey:cacheKey]; if (!image) { image = [UIImage imageWithContentsOfFile:_imagePaths[index]]; float desiredWidth = size.width; float desiredHeight = size.height; float actualHeight = image.size.height; float actualWidth = image.size.width; float imgRatio = actualWidth / actualHeight; float maxRatio = desiredWidth / desiredHeight; if(imgRatio != maxRatio) { if(imgRatio < maxRatio) { imgRatio = desiredHeight / actualHeight; actualWidth = imgRatio * actualWidth; actualHeight = desiredHeight; } else { imgRatio = desiredWidth / actualWidth; actualHeight = imgRatio * actualHeight; actualWidth = desiredWidth; } } CGRect rect = CGRectMake(0.0, 0.0, actualWidth, actualHeight); UIGraphicsBeginImageContextWithOptions(rect.size, FALSE, 0); // do right thing for retina [image drawInRect:rect]; image = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); // here johnny [_johnny setObject:image forKey:cacheKey]; } return image; }
Danblakemore
source share