使用UIImage和下载的图像进行缓存

时间:2014-04-12 17:00:38

标签: ios objective-c caching uiimage

我有一个使用完成块获取图像的类方法。将获取的UIImage添加到具有相关密钥的NSCache中。这似乎按预期工作,但是,在获取图像的方法中,我使用UIImage的{​​{1}}方法,我发现它不会缓存它的数据,只有imageWithData:

由于这一点,我可以理解得到内存警告,如何在不再需要的情况下确保使用imageNamed:的{​​{1}}方法加载的图像从内存中删除?

修改

以下是下载图像的方法的代码。

UIImage

编辑2

使用上述类方法获取和处理completionHandler中imageWithData:的方法。

- (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); }); }); } }); }); } } 子类中的方法。

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]; } }

的getter方法
NSCache

1 个答案:

答案 0 :(得分:0)

您可能最好使用SDWebImage,而不是滚动自己的图片下载和缓存解决方案。然后,您不必担心下载,缓存或任何其他问题。 SDWebImage也使用磁盘缓存,因此您不必担心释放内存。

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;
}];