2012-10-10 30 views
0

我有一个应用程序,它可以下载几个图像并将它们存储在手机中。总共可能需要大约20张图像。我需要能够根据用户所在的屏幕随意检索这些图像。这些图像将无限期存储,所以我不想使用临时目录。在iPhone上高效地存储和检索图像

目前我有这些方法

- (void) cacheImage: (NSString *) ImageURLString : (NSString *)imageName 
{ 
    NSURL *ImageURL = [NSURL URLWithString: ImageURLString]; 

    // Generate a unique path to a resource representing the image you want 

    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *docDir = [paths objectAtIndex: 0]; 
    NSString *docFile = [docDir stringByAppendingPathComponent: imageName]; 

    // Check for file existence 
    if(![[NSFileManager defaultManager] fileExistsAtPath: docFile]) 
    { 
     // The file doesn't exist, we should get a copy of it 

     // Fetch image 
     NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL]; 

     UIImage *image = [[UIImage alloc] initWithData: data]; 

     // Is it PNG or JPG/JPEG? 
     // Running the image representation function writes the data from the image to a file 
     if([ImageURLString rangeOfString: @".png" options: NSCaseInsensitiveSearch].location != NSNotFound) 
     { 

      [UIImagePNGRepresentation(image) writeToFile: docFile atomically: YES]; 

     } 
     else if([ImageURLString rangeOfString: @".jpg" options: NSCaseInsensitiveSearch].location != NSNotFound || 
       [ImageURLString rangeOfString: @".jpeg" options: NSCaseInsensitiveSearch].location != NSNotFound) 
     { 
      [UIImageJPEGRepresentation(image, 100) writeToFile: docFile atomically: YES]; 
     } 
    } 
} 

- (UIImage *) getCachedImage : (NSString *)imageName 
{ 

    NSArray *paths = NSSearchPathForDirectoriesInDomains 
    (NSDocumentDirectory, NSUserDomainMask, YES); 
    NSString *documentsDirectory = [paths objectAtIndex:0]; 
    NSString* cachedPath = [documentsDirectory stringByAppendingPathComponent:imageName]; 

    UIImage *image; 

    // Check for a cached version 
    if([[NSFileManager defaultManager] fileExistsAtPath: cachedPath]) 
    { 
     image = [UIImage imageWithContentsOfFile: cachedPath]; // this is the cached image 
    } 
    else 
    { 
     NSLog(@"Error getting image %@", imageName); 
    } 

    return image; 
} 

-(void)getImages 
{  

//example 
    NSString *image1URL = @"http://test/image1.png";   
    NSString *image2URL = @"http://test/image2.png";   
    NSString *image3URL = @"http://test/image3.png"; 

    [self cacheImage:sLogo: @"Image1"]; 
    [self cacheImage:sBlankNav: @"Image2"]; 
    [self cacheImage:buttonLarge :@"Image3"]; 

} 

-(void) storeImages 
{ 
    image1 = [self getCachedImage:@"Image1"]; 
    image2 = [self getCachedImage:@"Image2"]; 
    image3 = [self getCachedImage:@"Image3"]; 

} 

于是我就用这样的

Images *cache = [[Images alloc]init]; 
[cache storeImages]; 

代码的获取图像的方法被调用一次图片类命名时,应用程序首先开始得到这些图像之后,它不会再被调用,除非服务器上的图像被更新,我需要检索更新的图像。

该代码有效,但问题是当我导航到使用它的屏幕时,屏幕加载之前有一个非常小的延迟,因为它正在加载图像。

我的应用程序是一个选项卡式应用程序,所以它从选项卡1开始,点击实现代码的选项卡2,第一次加载时会稍微暂停。它不会持续很长时间,但它是显而易见的,非常烦人。之后就没问题了,因为它已经加载了。但是,使用导航控制器时,每次从第一个VC移动到第二个VC时,该方法都会再次被调用,所以每次浏览延迟时都会在那里。

图像不是很大,最大的是68kb,其他的比这小得多。目前我只用5张图片进行测试。有更有效的方式来存储和检索图像,或者我做错了我的代码?我需要能够在没有任何明显延迟的情况下检索这些图像,以便我的应用程序保持流畅,不生涩或笨拙。

在此先感谢!

回答

1

你有两个选择做在后台线程上的图像加载工作 - 使用Grand Central DispatchNSInvocationOperation 。 GCD可能被认为是两者中的更清洁者:

dispatch_queue_t q = dispatch_get_global_queue(0, 0); 
dispatch_queue_t main = dispatch_get_main_queue(); 
dispatch_async(q, ^{ 
     //load images here 
     dispatch_async(main, ^{ 
      // show on main thread here 
     }); 
}); 
+0

问题在于,检索图像时不会显示图像,然后会突然出现。它有点显而易见,在导航控制器中它不会很差,因为屏幕需要一秒钟才能导航,但对于标签屏幕,它们会立即出现,因此您会看到图像突然出现。不要以为这里有吗? – AdamM

+0

其实这个方法完美的作品。我所做的只是创建一个强大的AppDelegate中的图像对象的引用,在那里调用该方法中的商店图像,然后每当我需要使用这些图像时,只需调用在AppDelegate中创建的图像对象,因为图像已经存储。没有更多的延迟问题,并且没有更多的延迟创建图像。干杯!!! – AdamM

1

你有延迟,因为你下载的数据同步

// NSData *data = [[NSData alloc] initWithContentsOfURL: ImageURL]; 

尝试一些聪明的图书馆像SDWebImage: 它可以让你下载图像异步而你仍然可以显示本地图像(代理图像)。顺便说一句,你仍然可以免费获得缓存图片。所以,即使妳的地方,你仍然可以赶上前面下载的图片

https://github.com/rs/SDWebImage

A必须

+0

一个有趣的图书馆必须检查出来。然而,这并不是我遇到的下载问题,因为我只下载它们一次,它检索存储在手机上的图像是问题所在。我注意到图书馆也进行了缓存,它是否允许您在缓存后快速检索这些图像? – AdamM