iOS開發之記憶體與快取

yzf01發表於2021-09-09

使用快取的目的是為了使用的應用程式能更快速的響應使用者輸入,是程式高效的執行。有時候我們需要將遠端web伺服器獲取的資料快取起來,減少對同一個url多次請求。

記憶體快取我們可以使用sdk中的NSURLCache類。NSURLRequest需要一個快取引數來說明它請求的url何如快取資料的,我們先看下它的CachePolicy型別。

1、NSURLRequestUseProtocolCachePolicy NSURLRequest預設的cache policy,使用Protocol協議定義。
2、NSURLRequestReloadIgnoringCacheData 忽略快取直接從原始地址下載。
3、NSURLRequestReturnCacheDataElseLoad 只有在cache中不存在data時才從原始地址下載。
4、NSURLRequestReturnCacheDataDontLoad 只使用cache資料,如果不存在cache,請求失敗;用於沒有建立網路連線離線模式;
5、NSURLRequestReloadIgnoringLocalAndRemoteCacheData:忽略本地和遠端的快取資料,直接從原始地址下載,與NSURLRequestReloadIgnoringCacheData類似。
6NSURLRequestReloadRevalidatingCacheData:驗證本地資料與遠端資料是否相同,如果不同則下載遠端資料,否則使用本地資料。

NSURLCache還提供了很多方法,來方便我們實現應用程式的快取機制。下面我透過一個例子來說明,這個例子減少我們對同一個url多次請求。看下面程式碼:

-(IBAction) buttonPress:(id) sender
{
    NSString *paramURLAsString= @"";
    if ([paramURLAsString length] == 0){
        NSLog(@"Nil or empty URL is given");
        return;
    }
    NSURLCache *urlCache = [NSURLCache sharedURLCache];
    
    [urlCache setMemoryCapacity:1*1024*1024];
     //建立一個nsurl
    NSURL *url = [NSURL URLWithString:paramURLAsString];
        //建立一個請求
    NSMutableURLRequest *request =
    [NSMutableURLRequest
     requestWithURL:url
     cachePolicy:NSURLRequestUseProtocolCachePolicy
     timeoutInterval:60.0f];
     //從請求中獲取快取輸出
    NSCachedURLResponse *response =
    [urlCache cachedResponseForRequest:request];
    //判斷是否有快取
    if (response != nil){
        NSLog(@"如果有快取輸出,從快取中獲取資料");
        [request setCachePolicy:NSURLRequestReturnCacheDataDontLoad];
    }
    self.connection = nil;
    
    NSURLConnection *newConnection =
    [[NSURLConnection alloc] initWithRequest:request
                                    delegate:self
                            startImmediately:YES];
    self.connection = newConnection;
    [newConnection release];
}

這個例子中,我們請求url為的網站。如果這個url被快取了,我們直接從快取中獲取資料,否則從站點上重新獲取資料。我們設定了快取大小為1M。

使用下面程式碼,我將請求的過程列印出來:

- (void)  connection:(NSURLConnection *)connection
  didReceiveResponse:(NSURLResponse *)response{
    NSLog(@"將接收輸出");
}
- (NSURLRequest *)connection:(NSURLConnection *)connection
             willSendRequest:(NSURLRequest *)request
            redirectResponse:(NSURLResponse *)redirectResponse{
    NSLog(@"即將傳送請求");
    return(request);
}
- (void)connection:(NSURLConnection *)connection
    didReceiveData:(NSData *)data{
    NSLog(@"接受資料");
    NSLog(@"資料長度為 = %lu", (unsigned long)[data length]);
}
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection
                  willCacheResponse:(NSCachedURLResponse *)cachedResponse{
    NSLog(@"將快取輸出");
    return(cachedResponse);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
    NSLog(@"請求完成");
}
- (void)connection:(NSURLConnection *)connection
  didFailWithError:(NSError *)error{
    NSLog(@"請求失敗");
}

當我們第一次點選介面上的按鈕,列印的結果如下:

2011-07-30 18:50:24.910 Caching[3971:207] 即將傳送請求
2011-07-30 18:50:28.557 Caching[3971:207] 將接收輸出
2011-07-30 18:50:31.677 Caching[3971:207] 接受資料
2011-07-30 18:50:31.681 Caching[3971:207] 資料長度為 = 4414
2011-07-30 18:50:31.682 Caching[3971:207] 接受資料
2011-07-30 18:50:31.682 Caching[3971:207] 資料長度為 = 2996
2011-07-30 18:50:38.107 Caching[3971:207] 將快取輸出
2011-07-30 18:50:38.109 Caching[3971:207] 請求完成

在看我們第二次點選介面上的按鈕,列印結果如下:

2011-07-30 18:52:18.894 Caching[3971:207] 即將傳送請求
2011-07-30 18:52:18.895 Caching[3971:207] 將接收輸出
2011-07-30 18:52:18.895 Caching[3971:207] 接受資料
2011-07-30 18:52:18.896 Caching[3971:207] 資料長度為 = 7410
2011-07-30 18:52:18.896 Caching[3971:207] 請求完成

我們看到沒有“將快取輸出”一項,請求到的資料是第一次請求的累積,也就是第二次是從記憶體中獲取資料的。

總結:本文簡單的介紹了一下iOS的記憶體快取機制,下一篇文章將重點介紹一下本地快取機制。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/2334/viewspace-2808393/,如需轉載,請註明出處,否則將追究法律責任。

相關文章