如何在 ios 中正确缓存图像

How to cache images properly in ios

我正在使用 SDWebImage 来缓存图像。但它不起作用。我在 cellForRowAtIndexPath:

下以这种方式使用它
[cell.image sd_setImageWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"%@app/media/access/pictures?p=%@",baseurl,data.picPath]]
                 placeholderImage:[UIImage sd_animatedGIFNamed:@"image_loader.gif"] options:SDWebImageRefreshCached];

我想它是异步下载图像。但是我的应用程序在滚动 UITableView 时冻结了。向上滚动时也有网络使用,对我来说这不应该发生,因为我正在缓存它。

此外,我有一些逻辑可以根据 heightForRowAtIndexPath 下的图像大小调整 UIImageView 帧的大小,这可能是任何原因吗???

if(data.type == 2)
    {
        height = 260.00;
    }
    else if(data.type == 1)
    {
        height = self.view.frame.size.width/2 + 115;
    }
    else
    {
        NSString *filePath = [NSString stringWithFormat:@"%@app/media/access/pictures?p=%@",baseurl,data.picPath];
        self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]]];


        if (self.img.size.width > CGRectGetWidth(self.view.bounds)) {
            CGFloat ratio = self.img.size.height / self.img.size.width;
            return CGRectGetWidth(self.view.bounds) * ratio+120;
        } else {
            return self.img.size.height+110;
        }




    }

这是肯定的:

self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]]];

为什么要重新下载图片?您应该始终使用 SDWebImage.

添加 而不是做

NSString *filePath = [NSString stringWithFormat:@"%@app/media/access/pictures?p=%@",baseurl,data.picPath];
self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]]];

您必须先下载图像,因为 heightForRow 不会等待异步块。尝试使用 SDWebImage sharedDownloader 预加载它们。然后它们将在缓存中。

heightForRowAtIndexPath 中的以下代码导致了问题:

NSString *filePath = [NSString stringWithFormat:@"%@app/media/access/pictures?p=%@",baseurl,data.picPath];
        self.img = [UIImage imageWithData: [NSData dataWithContentsOfURL:[NSURL URLWithString:filePath]]];

每次滚动tableView都会执行代码,由于不是异步调用,会导致卡顿问题

编辑: 为避免这种情况,您可以这样做:

下载完成后即可使用,

[tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] 
                 withRowAnimation:UITableViewRowAnimationAutomatic];

这将再次调用

    -(CGFloat)tableView:(UITableView *)tableView
heightForRowAtIndexPath:(NSIndexPath *)indexPath

喜欢,

[cell.image sd_setImageWithURL:[NSURL URLWithString:[NSMutableString stringWithFormat:@"%@app/media/access/pictures?p=%@",baseurl,data.picPath]]

                                     completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {

                                         if (error) {

                                             NSLog(@"error: %@",error.description);


                                         }
                                         else{

                                             //get image height and return this height from HeightForRowAtIndexPath
                                             Height=image.size.height;

                                             //reloading row will call heightForRowAtIndexPath,where now you can return height got above
                                             [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObjects:indexPath, nil] withRowAnimation:UITableViewRowAnimationAutomatic];

                                             NSLog(@"Not an error in image download");
                                         }




                                     }];

编辑1:

查看已经缓存的图片,可以使用SDWebImage库的以下方法:

- (BOOL)diskImageExistsWithKey:(NSString *)key;

缓存键是要缓存的图像的应用程序唯一标识符。一般是图像的绝对URL

现在如果缓存中存在图片,则使用SDWebImage库的以下方法获取图片路径:

- (NSString *)defaultCachePathForKey:(NSString *)key;
- (NSString *)cachedFileNameForKey:(NSString *)key;

您可以像这样获取图像的路径:

NSString *ImageKey;//key for the image you want the path for
[[SDImageCache sharedImageCache] defaultCachePathForKey:ImageKey];

如果您不使用默认位置,您可以使用:

- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;

更多详细信息请查看此处:SDWebImage