Apakah mungkin untuk mencegah NSURLRequest dari data cache atau menghapus data cache mengikuti permintaan?

90

Di iPhone, saya melakukan permintaan HTTP menggunakan NSURLRequest untuk sebagian data. Alokasi objek melonjak dan saya menetapkan data yang sesuai. Ketika saya selesai dengan datanya, saya membebaskannya - namun instrumen tidak menunjukkan data apa pun yang telah dibebaskan!

Teori saya adalah bahwa secara default permintaan HTTP di-cache, namun - saya tidak ingin aplikasi iPhone saya menyimpan data ini ke cache.

Apakah ada cara untuk menghapus cache ini setelah ada permintaan atau mencegah data apa pun disimpan di cache?

Saya sudah mencoba menggunakan semua kebijakan cache yang didokumentasikan sedikit seperti di bawah ini:

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

tapi sepertinya tidak ada yang bisa membebaskan memori!

Nick Cartwright
sumber
Mungkinkah itu tidak terkait dengan cache? Sudahkah Anda mencoba memeriksa data untuk melihat apakah data yang seharusnya dimuat ulang ternyata adalah data lama? Mungkin daun bawang Anda berasal dari tempat lain. Bagaimana Anda menginisialisasi dan membebaskan NSURLRequests? Itu mungkin bisa membantu untuk mendiagnosis masalah.
lpfavreau
FYI - Jika Anda ingin menghapus file secara brute force, ada contoh kode untuk melakukannya di sini: salesforce.stackexchange.com/a/69736
zekel

Jawaban:

158

Biasanya lebih mudah membuat permintaan seperti ini

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

Kemudian buat koneksi

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

dan menerapkan metode koneksi: willCacheResponse: pada delegasi. Hanya mengembalikan nol harus melakukannya.

- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
  return nil;
}
tcurdt
sumber
Terima kasih banyak di sini atas bantuan Anda! Nick.
Nick Cartwright
1
Terima kasih atas gagasan itu - Saya menelepon layanan web SOAP seperti ini berulang kali dan menumbuhkan tumpukan tak terkendali meskipun kebocoran tidak menunjukkan ada yang salah. Saya mengoptimalkan selama berhari-hari dan akhirnya mencoba mencegah caching karena banyak objek CFURL * dari kerangka internal berkeliaran. Mengembalikan nil dari willCacheResponse adalah satu-satunya hal yang berhasil!
Bron Davies
15
Mengapa perlu melakukan keduanya NSURLRequestReloadIgnoringCacheData dan menerapkan connection:willCacheResponse:?
fabb
1
Hai, mungkinkah saya dapat menggunakan ini untuk memuat konten lokal? Di atas adalah untuk NSUrlConnection tetapi saya memuat data HTML lokal ke UIWebView menggunakan NSUrlRequest. Saya perlu menolak cache apa pun karena ada gambar yang masuk ke tampilan web dari SQLite dan memori meningkat dengan setiap pemuatan halaman. Terima kasih.
jim
7
@fabb, overriding connection:willCacheResponse:memungkinkan Anda untuk tidak menyimpan respons di cache. NSURLRequestReloadIgnoringCacheDatamenentukan bahwa koneksi harus memuat permintaan tanpa memeriksa cache. Yang pertama mungkin yang membantu mengelola alokasi memori.
Christopher Pickslay
12

Saya memiliki masalah yang sama di aplikasi saya ketika saya meminta info dari twitter. Dalam kasus saya, saya tidak perlu mempertahankan kredensial tersebut, jadi saya cukup menghapusnya menggunakan kode berikut:

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

Saya harap ini berhasil untuk seseorang :)


sumber
ini adalah solusi sempurna untuk masalah saya, saya mengalami masalah masuk kembali, karena kredensial disimpan dan secara otomatis dikirimkan oleh NSURLConnection, terima kasih banyak, ini sangat membantu saya :)
RVN
Terima kasih itu berhasil untuk saya, saya sangat menghargai saran Anda. Sebenarnya masalah saya adalah NSURLRequest menyimpan username dan password. Jadi ini membantu untuk menghapus kredensial Pengguna dari cache ...
Nilesh Kikani
10

Jika Anda menggunakan NSURLConnection, lihat delegasi:

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

Nilai Kembali

Respons aktual yang di-cache untuk disimpan di cache. Delegasi dapat mengembalikan cachedResponse tanpa modifikasi, mengembalikan respons cache yang dimodifikasi, atau mengembalikan nihil jika tidak ada respons yang di-cache harus disimpan untuk koneksi.

catlan
sumber
Terima kasih banyak di sini. Jejak memori aplikasi saya tiba-tiba berkurang setengahnya! Nick.
Nick Cartwright
9

Jika Anda menggunakan NSURLSession, solusi lain untuk mencegah permintaan dan parameter ditulis ke Cache.dbiOS yang dibuat dalam Cachesdirektori aplikasi , adalah dengan menyetel NSURLCachekonfigurasi sesi ke memori ukuran 0 dan cache disk ukuran 0, misalnya.

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

atau seperti yang disebutkan di atas disetel pada tingkat cache global

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

Agaknya 0 untuk ukuran disk yang menghentikan penulisan iOS ke disk, tetapi jika Anda memiliki kebijakan untuk reloadIgnoringLocalCacheDataitu, Anda mungkin juga tidak tertarik dengan cache memori.

Catatan Ini akan mencegah semua Caches/Cache.db(permintaan & tanggapan) atau Caches/fsCachedData/folder (data tanggapan) dibuat. Kami telah memutuskan untuk mengambil pendekatan ini di aplikasi untuk tujuan keamanan karena kami tidak ingin permintaan kami disimpan di cache disk.

Jika ada yang tahu apakah ada cara untuk berhenti hanya meminta cache tetapi menyimpan cache data respons dari mekanisme Pemuatan URL iOS, saya akan tertarik untuk mengetahuinya. (tidak ada API atau dokumentasi resmi tentang ini dari apa yang saya tahu)

Shagun Madhikarmi
sumber
7

Jika tidak spesifik untuk satu permintaan (Anda ingin menonaktifkan cache untuk seluruh aplikasi) di bawah ini adalah opsi terbaik. Tambahkan kode ini di delegasi aplikasi atau berdasarkan kebutuhan Anda di mana saja

        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];
Sanjeev Rao
sumber
7
Berfungsi bagus untuk saya, tetapi Anda bisa menggunakan 0 daripada melakukan perkalian yang hanya berakhir di 0.
Gary Riches
1
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];

Dengan asumsi server diimplementasikan dengan benar, meletakkan Cache-Control:no-storeheader dalam permintaan akan menghasilkan respons server dengan header yang sama, sehingga menyebabkan NSURLCachedata respons tidak disimpan pada disk.

Oleh karena itu, tidak perlu pendekatan senapan untuk menonaktifkan NSURLCachecache disk.

PS: Menambahkan header seharusnya berfungsi untuk semua kerangka kerja HTTP, seperti AFNetworking

Yuri Brigance
sumber