Bir NSURLRequest'in verileri önbelleğe almasını önlemek veya bir talepten sonra önbelleğe alınmış verileri kaldırmak mümkün müdür?


90

İPhone'da, bir veri yığını için NSURLRequest'i kullanarak bir HTTP isteği gerçekleştiriyorum. Nesne tahsisi yükseliyor ve verileri buna göre atıyorum. Verileri bitirdiğimde, buna göre serbest bırakıyorum - ancak aletler serbest bırakılmış herhangi bir veri göstermiyor!

Teorim, varsayılan olarak HTTP isteklerinin önbelleğe alınmasıdır, ancak iPhone uygulamamın bu verileri önbelleğe almasını istemiyorum.

Bir istekten sonra bu önbelleği temizlemenin veya herhangi bir verinin ilk etapta önbelleğe alınmasını önlemenin bir yolu var mı?

Aşağıda belgelenen tüm önbellek politikalarını aşağıda olduğu gibi kullanmayı denedim:

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

ama hiçbir şey hafızayı boşaltmıyor gibi görünüyor!


Önbellekle ilgili olmaması mümkün müdür? Yeniden yüklenmesi gereken verilerin aslında eski veri olup olmadığını görmek için verileri incelemeyi denediniz mi? Belki pırasanız başka bir yerden geliyordur. NSURL Taleplerini nasıl başlatır ve serbest bırakırsınız? Bu, sorunu teşhis etmede yardımcı olabilir.
lpfavreau

Bilginize - Dosyaları kaba kuvvet kullanarak kaldırmak istiyorsanız, burada bunu yapmak için örnek kod var: salesforce.stackexchange.com/a/69736
zekel

Yanıtlar:


158

Genellikle böyle bir istek oluşturmak daha kolaydır

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

Ardından bağlantıyı oluşturun

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

ve temsilci üzerinde bağlantı: willCacheResponse: yöntemini uygulayın. Sadece sıfır döndürmek bunu yapmalı.

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

Yardımın için çok teşekkürler! Nick.
Nick Cartwright

1
Bu fikir için teşekkürler - defalarca böyle bir SOAP web servisini arıyordum ve sızıntılar yanlış bir şey göstermese de yığın kontrolsüz bir şekilde büyüyordu. Günlerce optimize ettim ve nihayet iç çerçeveden birçok CFURL * nesnesi ortalıkta dolaştığı için önbelleğe almayı önlemeye çalıştım. WillCacheResponse'den sıfır döndürmek işe yarayan tek şeydi!
Bron Davies

15
Neden ikisini birden yapmak NSURLRequestReloadIgnoringCacheData ve uygulamak gerekli connection:willCacheResponse:?
fabb

1
Merhaba, bunu yerel içerik yüklemek için kullanabilir miyim? Yukarıdakiler NSUrlConnection içindir, ancak NSUrlRequest kullanarak yerel HTML verilerini UIWebView'a yüklüyorum. SQLite'den web görünümüne giden görüntüler olduğu ve her sayfa yüklemede bellek arttığı için herhangi bir önbelleği reddetmem gerekiyor. Teşekkürler.
jim

7
@fabb, geçersiz kılma connection:willCacheResponse:yanıtı önbellekte saklamamanıza izin verir. NSURLRequestReloadIgnoringCacheDatabağlantının, önbelleği kontrol etmeden isteği yüklemesi gerektiğini belirtir. İlki muhtemelen bellek tahsisini yönetmeye yardımcı olan şeydir.
Christopher Pickslay

12

Twitter'dan bilgi istediğimde uygulamamda aynı sorunu yaşıyorum. Benim durumumda bu kimlik bilgilerini korumam gerekmedi, bu yüzden bir sonraki kodu kullanarak onları basitçe silebilirim:

- (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];
    }
}

Umarım birisi için işe yarar :)


bu benim sorunum için mükemmel bir çözümdü, yeniden oturum açma sorunum vardı, çünkü kimlik bilgileri depolandı ve NSURLConnection tarafından otomatik olarak gönderildi, çok teşekkürler, bu bana çok yardımcı oldu :)
RVN

Teşekkürler benim için çalışıyor, öneriniz için gerçekten minnettarım. Aslında benim sorunum NSURLRequest'in kullanıcı adı ve parolayı depolamasıdır. Bu, Kullanıcı kimlik bilgilerini önbellekten kaldırmaya yardımcı olur ...
Nilesh Kikani

10

NSURLConnection kullanıyorsanız, temsilciye bir göz atın:

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

Geri dönüş değeri

Önbellekte saklanacak gerçek önbelleğe alınmış yanıt. Temsilci, cachedResponse'u değiştirilmemiş olarak döndürebilir, değiştirilmiş bir önbelleğe alınmış yanıt döndürebilir veya bağlantı için önbelleğe alınmış yanıt saklanmayacaksa nil döndürebilir.


Burada çok teşekkürler. Uygulamamın bellek ayak izi aniden yarıya indi! Nick.
Nick Cartwright

9

Eğer kullanıyorsanız NSURLSessionisteği önlemek için, başka bir çözüm ve parametreler yazılıyor Cache.dbiOS uygulamasının içinde oluşturur Cachesdizine, ayarlamaktır NSURLCachebir oturumun yapılandırma için 0 boyutu bellek ve 0 boyutu diskte önbellek örn

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

veya yukarıda bahsedildiği gibi genel bir önbellek düzeyinde ayarlanır

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

Muhtemelen iOS'un diske yazmasını durduran disk boyutu 0'dır, ancak bir politikanız reloadIgnoringLocalCacheDatavarsa, muhtemelen bellek önbelleğe alma ile de ilgilenmiyorsunuzdur.

Not Bu, herhangi bir Caches/Cache.db(istek ve yanıt) veya Caches/fsCachedData/klasör (yanıt verileri) oluşturulmasını tamamen önleyecektir . İsteklerimizin hiçbir zaman disk önbelleğinde saklanmasını istemediğimizden, bu yaklaşımı güvenlik amacıyla bir uygulamada kullanmaya karar verdik.

Herhangi biri yalnızca önbelleğe almayı durdurmanın, ancak yanıt verilerini iOS URL Yükleme mekanizmasından önbelleğe almanın bir yolu olduğunu biliyorsa, bilmek isterim. (Anlayabildiğim kadarıyla bununla ilgili API veya resmi belge yok)


7

Tek bir isteğe özel değilse (U tüm uygulama için önbelleği devre dışı bırakmak istiyorsanız) aşağıdaki en iyi seçenektir.Bu kodu uygulama temsilcisine ekleyin veya herhangi bir yerde ihtiyacınıza göre ekleyin

        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
Benim için harika çalışıyor, ancak yine de 0'da biten çarpma işlemini yapmak yerine sadece 0'ı kullanabilirsiniz.
Gary Riches

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

Sunucunun doğru şekilde uygulandığını varsayarsak, Cache-Control:no-storebaşlığın isteğe NSURLCacheeklenmesi aynı başlığa sahip bir sunucu yanıtı oluşturacak ve böylece yanıt verilerinin diskte depolanmamasına neden olacaktır.

Bu nedenle, NSURLCachedisk önbelleğini devre dışı bırakmak için shotgun yaklaşımına gerek yoktur .

Not: Başlığın eklenmesi gibi tüm HTTP çerçeveleri için çalışmalıdır. AFNetworking

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.