用UIImage和下载的图像进行caching

我有一个类方法,用完成块获取图像。 这个提取的UIImage被添加到一个带有相关密钥的NSCache。 这似乎工作正常,但是,在获取图像的方法,我使用UIImageimageWithData:方法,我发现不会caching它的数据,只有imageNamed:做。

我可以理解的获取内存警告正因为如此,我怎么确保用UIImageimageWithData:方法加载的图像不再需要时从内存中删除?

编辑

这里是下载图像的方法的代码。

 - (void)imageForFootageSize:(FootageSize)footageSize withCompletionHandler:(void (^)(UIImage *image))completionBlock { if (completionBlock) { __block UIImage *image; // Try getting local image from disk. // __block NSURL *imageURL = [self localURLForFootageSize:footageSize]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ image = [UIImage imageWithData:[NSData dataWithContentsOfURL:imageURL]]; dispatch_async(dispatch_get_main_queue(), ^{ if (image) { completionBlock(image); } else { // // Otherwise try getting remote image. // imageURL = [self remoteURLForFootageSize:footageSize]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSData *imageData = [NSData dataWithContentsOfURL:imageURL]; dispatch_async(dispatch_get_main_queue(), ^{ image = [UIImage imageWithData:imageData]; if (image) { // // Save remote image to disk // NSURL *photoDirectoryURL = [Footage localURLForDirectory]; // Create the folder(s) where the photos are stored. // [[NSFileManager defaultManager] createDirectoryAtPath:[photoDirectoryURL path] withIntermediateDirectories:YES attributes:nil error:nil]; // Save photo // NSString *localPath = [[self localURLForFootageSize:footageSize] path]; [imageData writeToFile:localPath atomically:YES]; } completionBlock(image); }); }); } }); }); } } 

编辑2

使用上面的类方法在completionHandler中获取和处理UIImage的方法。

UICollectionViewCell子类中的方法。

 - (void)setPhoto:(Photo *)photo withImage:(UIImage *)image { [self setBackgroundColor:[UIColor blackColor]]; [self.imageView setBackgroundColor:[UIColor clearColor]]; if (photo && !image) { [photo imageForFootageSize:[Footage footageSizeThatBestFitsRect:self.bounds] withCompletionHandler:^(UIImage *image) { if ([self.delegate respondsToSelector:@selector(galleryPhotoCollectionViewCell:didLoadImage:)]) { [self.delegate galleryPhotoCollectionViewCell:self didLoadImage:image]; } image = nil; }]; } [self.imageView setImage:image]; BOOL isPhotoAvailable = (BOOL)(image); [self.imageView setHidden:!isPhotoAvailable]; [self.activityIndicatorView setHidden:isPhotoAvailable]; } 

UICollectionView数据源委托中的方法

 - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath { DIGalleryPhotoCollectionViewCell *photoCell = [collectionView dequeueReusableCellWithReuseIdentifier:photoCellIdentifier forIndexPath:indexPath]; [photoCell setDelegate:self]; Footage *footage = [self footageForIndexPath:indexPath]; Photo *photo = ([footage isKindOfClass:[Photo class]]) ? (Photo *)footage : nil; if (photo) { // // Photo // [photoCell setPhoto:photo withImage:[self.galleryCache objectForKey:photo.footageID]]; } return photoCell; } 

以下是其他相关的方法:

 - (void)galleryPhotoCollectionViewCell:(DIGalleryPhotoCollectionViewCell *)cell didLoadImage:(UIImage *)image { NSIndexPath *indexPath = [self.galleryCollectionView indexPathForCell:cell]; Footage *footage = [self footageForIndexPath:indexPath]; if ([footage isKindOfClass:[Footage class]]) { Photo *photo = (Photo *)footage; UIImage *cachedImage = [self.galleryCache objectForKey:photo.footageID]; if (!cachedImage) { cachedImage = image; [self.galleryCache setObject:image forKey:photo.footageID]; } [cell setPhoto:photo withImage:image]; } } 

而且我的NSCache属性galleryCache getter方法

 - (NSCache *)galleryCache { if (!_galleryCache) { _galleryCache = [[NSCache alloc] init]; } return _galleryCache; } 

而不是滚动自己的图像下载和caching解决scheme,你可能会更好使用SDWebImage 。 那么你不必担心下载,caching或任何事情。 SDWebImage也使用磁盘caching,所以你不必担心释放内存。

 SDWebImageManager *manager = [SDWebImageManager sharedManager]; [manager downloadWithURL:imageURL options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) { // progression tracking code } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) { if (image) { // do something with image } }]; 

我不确定,但你也可能有一个保留周期:

 __weak typeof(self) weakSelf = self; [photo imageForFootageSize:[Footage footageSizeThatBestFitsRect:self.bounds] withCompletionHandler:^(UIImage *image) { if ([weakSelf.delegate respondsToSelector:@selector(galleryPhotoCollectionViewCell:didLoadImage:)]) { [weakSelf.delegate galleryPhotoCollectionViewCell:weakSelf didLoadImage:image]; } image = nil; }];