强制iOS上的图像加载预加载

时间:2012-02-10 09:35:22

标签: ios image preload

我想预先加载图像,当我将他们的UIImageView添加到我的currentView时,PNG已经在内存中,加载,充气等。

从这次时间分析中可以看出,图像在显示时会被加载: enter image description here

与此同时,我之前已经预先加载了这些图片。就在我加载该视图时,我使用该代码彻底创建了这些动画的所有图像和图像视图:

- (UIImageView*)createAnimationForReel:(NSString*)reel ofType:(NSString*)type usingFrames:(NSInteger)frames{
    UIImageView *imageView = [[UIImageView alloc] init];
    NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:frames];

    for (int i=0;i<frames;i++){
        NSString *image;
        if(i<10){
            image = [NSString stringWithFormat:@"%@_0%i", reel, i];
        } else {
            image = [NSString stringWithFormat:@"%@_%i", reel, i];
        }
        NSString *path = [[NSBundle mainBundle] pathForResource:image ofType:@"png" inDirectory:type];
        UIImage *anImage = [[UIImage alloc] initWithContentsOfFile:path];
        [imageArray addObject:anImage];
    }
    imageView.animationImages = [NSArray arrayWithArray:imageArray];
    imageView.animationDuration = 2.0;
    return imageView;
}

当我阅读文档时,它说:“此方法将图像数据加载到内存中并将其标记为可清除。如果数据被清除并需要重新加载,则图像对象将再次从指定路径加载该数据。 “谈论initWithContentOfFile。所以我的图像“应该”被加载。

但不是。

我的反思当然缺少一些东西。但是什么?

3 个答案:

答案 0 :(得分:13)

要强制完全预加载UIImage,你需要实际绘制它,或者看起来如此。例如使用:

- (void)preload:(UIImage *)image
{
    CGImageRef ref = image.CGImage;
    size_t width = CGImageGetWidth(ref);
    size_t height = CGImageGetHeight(ref);
    CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(NULL, width, height, 8, width * 4, space, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedFirst);
    CGColorSpaceRelease(space);
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), ref);
    CGContextRelease(context);
}

不漂亮,但它使图像绘制速度提高了4倍。我在iPhone 4S上用1 MB 640×1136 PNG测试了这个:

  • 在没有预加载的情况下绘制它需要大约80毫秒。
  • 预加载图像标题大约需要10毫秒,但之后不会加速绘图。
  • 通过数据提供程序预加载数据大约需要100毫秒,但之后很难加快绘图速度。
  • 上面的代码中所示的绘图预加载需要100毫秒,但下一个绘图只需20毫秒。

检查https://gist.github.com/3923434以获取测试代码。

答案 1 :(得分:0)

方法是使用ImageIO框架(iOS 4.0+)并执行类似的操作:

NSDictionary* dict = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:(id)kCGImageSourceShouldCache];

CGImageSourceRef source = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
CGImageRef cgImage = CGImageSourceCreateImageAtIndex(source, 0, (CFDictionaryRef)dict);

UIImage* retImage = [UIImage imageWithCGImage:cgImage];
CGImageRelease(cgImage);
CFRelease(source);

答案 2 :(得分:0)

狮子座答案几乎没有给我任何速度加载提升。只有在我第一次第二次预加载一张图像后,效果才会显着。例如,如果通过按钮单击调用预加载,如果初始加载为200ms,则首次预加载会提供大约40ms的提升。它并不多。

为了解决我的问题,我刚刚创建了隐藏的imageViews并将它们添加到视图层次结构中,我需要预加载。接下来加载这些图像大约需要10毫秒。