试图在字典中缓存uiImages,似乎不会影响加载时间

时间:2011-01-29 15:32:34

标签: caching ios uitableview uiimage

我正在使用标准缓存方法来缓存从Documents目录加载的一些UIImages。图像显示在UITableView中。它们非常大 - 图像本身高达600x600,并且在240x180的图像视图中显示(在视网膜显示器上,因此差异不大)。

当新细胞即将上线时,实时加载图像会导致一些延迟。所以我在处理图像的对象中实现了一个缓存方法:

- (UIImage *)imageWithStyle:(NSString *)styleName {
    NSLog(@"looking for image %@", self.imageFileName);

    /* if we have a cached image in dictionary, return it */
    if (imageCache == nil) imageCache = [[NSMutableDictionary alloc] init];
    UIImage *returnImage = [imageCache objectForKey:styleName];
    if (returnImage != nil) {
        NSLog(@"returning cached image");
        return returnImage;
    }

    /* otherwise, look for image at path */
    NSString *path = [self cacheFilePathWithStyle:styleName];
    UIImage * originalImage = [[UIImage alloc] initWithContentsOfFile:path];

    /* if image doesnt exist at path, start download and return nil */
    if (originalImage == nil) {
        NSLog(@"image not found. downloading.");
        [self downloadImageFromS3];
        return nil;
    }

    /* found image at path */

    /* scale image for screen */
    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)] && [[UIScreen mainScreen] scale] == 2){
        returnImage = [UIImage imageWithCGImage:[[originalImage autorelease] CGImage] scale:2.0 orientation:UIImageOrientationUp];
        NSLog(@"scaling image for retina");
    } else {
        returnImage = [originalImage autorelease];
        NSLog(@"image scaled for standard resolution");
    }

    /* cache image in dictionary */
    NSLog(@"caching image");
    [imageCache setObject:returnImage forKey:styleName];

    return returnImage;
}

在屏幕上出现tableview之前,我强制所有图像处理对象运行此缓存方法,以确保图像存在于字典中,以便在需要显示时检索。通过NSLog,我可以看到事情正在发挥作用。

我现在正在获得无滞后性能,但只有在图像出现在屏幕上之后才会出现。所以,当我最初看到tableview时,我向下滚动并且NSLogs告诉我正在从缓存中检索图像,但我仍然得到相同的加载延迟。在一个单元格出现在屏幕上一次之后,它会加载而没有延迟。

这里有什么我想念的吗?还有什么我必须要实际缓存图像吗?加载它并将其放入字典似乎没有办法。

谢谢!

更新

我现在已经放弃了。有一些尝试通过在新的上下文中绘制来强制图像加载,但此时我不熟悉核心图形编程。我已经尝试了一些人们共享的代码,但没有运气。

相反,我会在tableview滚动时显示图像的低分辨率版本,并在tableview停止滚动时加载高分辨率版本,如通过其委托方法所宣布的那样。至少我知道这种方法适用于任意数量的图像。

2 个答案:

答案 0 :(得分:0)

来自-[UIImage initWithContentsOfFile:]的文档:

  

此方法将图像数据加载到内存中并将其标记为可清除。如果数据被清除并需要重新加载,则图像对象将从指定路径再次加载该数据。

我的猜测是,通过将所有图像加载到内存中,您的应用程序会消耗太多内存,导致UIImage类释放它稍后可以从文件重新加载的图像数据。

答案 1 :(得分:0)

如果您使用[UIImage imageNamed:],它将为您完成所有这些缓存业务。无需滚动自己的缓存,然后想知道它是否正常工作。

使用该方法的好处和缺点。好处:如果你使用相同的图像文件两次,它实际上不会加载两次,从而节省了你的内存。缺点:缓存会对记忆产生很大的影响,无论你是否自己动手,你都会想到这么做。