Có thể ngăn NSURLRequest lưu vào bộ nhớ đệm dữ liệu hoặc xóa dữ liệu đã lưu trong bộ nhớ cache sau một yêu cầu không?


89

Trên iPhone, tôi thực hiện một yêu cầu HTTP bằng NSURLRequest cho một phần dữ liệu. Phân bổ đối tượng tăng đột biến và tôi chỉ định dữ liệu cho phù hợp. Khi tôi hoàn thành dữ liệu, tôi giải phóng nó tương ứng - tuy nhiên các công cụ không hiển thị bất kỳ dữ liệu nào đã được giải phóng!

Tuy nhiên, lý thuyết của tôi là các yêu cầu HTTP mặc định được lưu trong bộ đệm - tôi không muốn ứng dụng iPhone của mình lưu vào bộ đệm dữ liệu này.

Có cách nào để xóa bộ nhớ cache này sau một yêu cầu hoặc ngăn bất kỳ dữ liệu nào được lưu vào bộ nhớ cache ngay từ đầu không?

Tôi đã thử sử dụng tất cả các chính sách bộ nhớ cache được ghi lại giống như bên dưới:

NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;

nhưng dường như không có gì để giải phóng bộ nhớ!


Có thể nó không liên quan đến bộ nhớ cache không? Bạn đã thử kiểm tra dữ liệu để xem liệu dữ liệu đáng lẽ được tải lại có thực sự là dữ liệu cũ không? Có thể tỏi tây của bạn đến từ nơi khác. Làm cách nào để bạn khởi tạo và giải phóng các NSURLRequests? Điều đó có thể giúp ích cho việc chẩn đoán sự cố.
lpfavreau

FYI - Nếu bạn muốn xóa các tệp bằng bạo lực, có mã ví dụ để làm điều đó ở đây: salesforce.stackexchange.com/a/69736
zekel

Câu trả lời:


157

Thông thường, việc tạo yêu cầu như thế này sẽ dễ dàng hơn

NSURLRequest *request = [NSURLRequest requestWithURL:url
      cachePolicy:NSURLRequestReloadIgnoringCacheData
      timeoutInterval:60.0];

Sau đó tạo kết nối

NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
       delegate:self];

và triển khai phương thức kết nối: willCacheResponse: trên đại biểu. Chỉ cần trả về nil nên làm điều đó.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}

Cảm ơn rất nhiều ở đây cho sự giúp đỡ của bạn! Nick.
Nick Cartwright

1
Cảm ơn vì ý tưởng đó - tôi đã gọi một dịch vụ web SOAP như thế này liên tục và nó đang tăng lên một cách không kiểm soát được mặc dù các rò rỉ không cho thấy bất cứ điều gì sai. Tôi đã tối ưu hóa trong nhiều ngày và cuối cùng đã cố gắng ngăn chặn bộ nhớ đệm vì rất nhiều đối tượng CFURL * từ khung nội bộ bị treo xung quanh. Trả lại nil từ willCacheResponse là thứ duy nhất hoạt động!
Bron Davies

15
Tại sao cần phải làm cả hai NSURLRequestReloadIgnoringCacheData thực hiện connection:willCacheResponse:?
fabb

1
Xin chào, tôi có thể sử dụng cái này để tải nội dung cục bộ không? Ở trên là dành cho NSUrlConnection nhưng tôi đang tải dữ liệu HTML cục bộ vào UIWebView bằng NSUrlRequest. Tôi cần từ chối bất kỳ bộ nhớ đệm nào vì có hình ảnh đi vào webview từ SQLite và bộ nhớ đang tăng lên với mỗi lần tải trang. Cảm ơn.
jim

7
@fabb, ghi đè connection:willCacheResponse:cho phép bạn không lưu phản hồi trong bộ nhớ đệm. NSURLRequestReloadIgnoringCacheDatachỉ định rằng kết nối sẽ tải yêu cầu mà không cần kiểm tra bộ đệm. Trước đây có lẽ là thứ giúp quản lý phân bổ bộ nhớ.
Christopher Pickslay

12

Tôi gặp vấn đề tương tự trong ứng dụng của mình khi tôi yêu cầu thông tin từ twitter. Trong trường hợp của tôi, tôi không cần giữ lại các thông tin đăng nhập đó, vì vậy tôi chỉ cần xóa chúng bằng cách sử dụng mã tiếp theo:

- (void) eraseCredentials{
NSURLCredentialStorage *credentialsStorage = [NSURLCredentialStorage sharedCredentialStorage];
NSDictionary *allCredentials = [credentialsStorage allCredentials];

//iterate through all credentials to find the twitter host
for (NSURLProtectionSpace *protectionSpace in allCredentials)
    if ([[protectionSpace host] isEqualToString:@"twitter.com"]){
        //to get the twitter's credentials
        NSDictionary *credentials = [credentialsStorage credentialsForProtectionSpace:protectionSpace];
        //iterate through twitter's credentials, and erase them all
        for (NSString *credentialKey in credentials)
            [credentialsStorage removeCredential:[credentials objectForKey:credentialKey] forProtectionSpace:protectionSpace];
    }
}

Tôi hy vọng nó có hiệu quả với ai đó :)


đây là một giải pháp hoàn hảo cho vấn đề của tôi, tôi đã gặp sự cố đăng nhập lại, vì thông tin đăng nhập đã được lưu trữ và tự động được gửi bởi NSURLConnection, cảm ơn rất nhiều, điều này đã giúp tôi rất nhiều thời gian :)
RVN

Cảm ơn nó đã làm việc cho tôi, tôi thực sự đánh giá cao đề xuất của bạn. Trên thực tế, vấn đề của tôi là NSURLRequest lưu trữ tên người dùng và mật khẩu. Vì vậy, sự giúp đỡ này để loại bỏ tài khoản chứng từ bộ nhớ cache ...
Nilesh Kikani

10

Nếu bạn sử dụng NSURLConnection, hãy xem ủy quyền:

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse

Giá trị trả lại

Phản hồi thực tế được lưu trong bộ nhớ cache để lưu trong bộ nhớ cache. Người được ủy quyền có thể trả về cacheResponse chưa được sửa đổi, trả về phản hồi được lưu trong bộ nhớ cache đã sửa đổi hoặc trả về nil nếu không có phản hồi đã lưu trong bộ nhớ cache nào được lưu trữ cho kết nối.


Cảm ơn rất nhiều ở đây. Dấu chân bộ nhớ của ứng dụng của tôi đột nhiên giảm một nửa! Nick.
Nick Cartwright

9

Nếu bạn đang sử dụng NSURLSession, một giải pháp khác để ngăn chặn yêu cầu và thông số được ghi vào Cache.dbiOS tạo trong Cachesthư mục của ứng dụng , đó là đặt NSURLCachecấu hình của phiên thành bộ nhớ kích thước 0 và bộ nhớ đệm đĩa kích thước 0, ví dụ:

let configuration = URLSessionConfiguration.default    
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)

hoặc như đã đề cập ở trên được đặt ở cấp bộ nhớ cache toàn cầu

URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)

Có lẽ đó là 0 cho kích thước ổ đĩa ngăn iOS ghi vào đĩa nhưng nếu bạn có chính sách reloadIgnoringLocalCacheDatathì có thể bạn cũng không quan tâm đến bộ nhớ đệm.

Lưu ý Điều này sẽ ngăn bất kỳ Caches/Cache.db(yêu cầu và phản hồi) hoặc Caches/fsCachedData/thư mục (dữ liệu phản hồi) được tạo. Chúng tôi đã quyết định thực hiện phương pháp này trong một ứng dụng vì mục đích bảo mật vì chúng tôi không muốn các yêu cầu của mình được lưu trữ trên bộ nhớ cache của đĩa.

Nếu ai đó biết có cách nào để dừng chỉ yêu cầu lưu vào bộ nhớ đệm mà vẫn giữ bộ nhớ đệm dữ liệu phản hồi từ cơ chế Tải URL của iOS, tôi rất muốn biết. (không có API hoặc tài liệu chính thức về điều này từ những gì tôi có thể nói)


7

Nếu không cụ thể cho một yêu cầu duy nhất (Bạn muốn tắt bộ nhớ cache cho toàn bộ ứng dụng) thì bên dưới là lựa chọn tốt nhất. Thêm mã này vào ứng dụng ủy quyền hoặc dựa trên nhu cầu của bạn bất kỳ nơi nào

        int cacheSizeMemory = 0*4*1024*1024; // 0MB
        int cacheSizeDisk = 0*32*1024*1024; // 0MB
        NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
        [NSURLCache setSharedURLCache:sharedCache];

7
Hoạt động tốt đối với tôi, nhưng bạn chỉ có thể sử dụng 0 thay vì thực hiện phép nhân chỉ kết thúc bằng 0 dù sao.
Gary Riches

1
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

Giả sử máy chủ được triển khai chính xác, việc đặt Cache-Control:no-storetiêu đề trong yêu cầu sẽ tạo ra phản hồi máy chủ có cùng tiêu đề, do đó NSURLCachekhông lưu trữ dữ liệu phản hồi trên đĩa.

Do đó, không cần đến cách tiếp cận shotgun để vô hiệu hóa NSURLCachebộ nhớ đệm đĩa.

Tái bút: Thêm tiêu đề sẽ hoạt động cho tất cả các khung HTTP, như AFNetworking

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.