2012-10-10 63 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