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

Caching 试图在字典中缓存uiImages,不会';似乎不会影响加载时间,caching,ios,uitableview,uiimage,Caching,Ios,Uitableview,Uiimage,我使用标准的缓存方法来缓存从Documents目录加载的一些UIImage。图像显示在UITableView中。它们非常大–图像本身高达600x600,并以240x180的图像视图显示(在视网膜显示器上,因此分辨率差异不大) 当屏幕上即将出现新的单元格时,实时加载图像会导致一些延迟。因此,我在处理图像的对象中实现了一个缓存方法: - (UIImage *)imageWithStyle:(NSString *)styleName { NSLog(@"looking for image %@

我使用标准的缓存方法来缓存从Documents目录加载的一些UIImage。图像显示在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停止滚动时加载高分辨率版本,正如通过其委托方法宣布的那样。至少我知道这种方法可以处理任意数量的图像。

来自
-[UIImage initWithContentsOfFile:
的文档:

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


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

如果你使用
[UIImage imageNamed://code>,它将为你完成所有缓存业务。无需滚动自己的缓存,然后怀疑它是否工作


使用这种方法有好处也有坏处。好处:如果您使用同一个图像文件两次,它实际上不会加载两次,从而节省内存。缺点:缓存对内存有很大的影响,无论您是否使用自己的缓存,您都需要认真考虑如何使用它。

谢谢您的回复!嗯,这似乎是一个很好的猜测,但一旦我滚动了整个列表视图(大约30幅图像),我就不再有加载延迟了。因此,似乎所有图像都在该点上同时缓存,没有任何问题。首先,我将尝试缓存前10个左右的图像,看看是否有区别。如果只缓存少数图像,则没有区别。我还尝试使用imageWithContentOfFile,它不缓存图像(这是一个好主意,因为我自己缓存图像)。运气不好。可能是
UIImage
延迟加载图像(即,仅当图像在屏幕上绘制时才会加载)。文档中说了一些其他的东西,但这可以解释您看到的行为。谢谢,Ole。我想你是对的。我将寻找一种方法来强制加载。我正在尝试这样的解决方案,但还没有运气。谢谢你的回复!我正在从documents目录加载图像,因此ImageName:不是立即选项。这就是我以这种方式缓存图像的原因。但是,我并没有考虑到内容也会缓存图像,正如奥勒指出的那样。也许我在这里太努力了…