Sur iPhone, j'exécute une requête HTTP à l'aide de NSURLRequest pour un bloc de données. Les pics d’allocation d’objets et j’assigne les données en conséquence. Lorsque je termine avec les données, je les libère en conséquence - cependant, les instruments ne montrent aucune donnée libérée!
Ma théorie est que, par défaut, les demandes HTTP sont mises en cache - je ne veux pas que mon application iPhone mette en cache ces données.
Existe-t-il un moyen d'effacer ce cache après une demande ou d'empêcher que des données soient mises en cache en premier lieu?
J'ai essayé d'utiliser toutes les politiques de cache documentées un peu comme ci-dessous:
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
mais rien ne semble libérer la mémoire!
Généralement, il est plus facile de créer une requête comme celle-ci.
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0];
Puis créez la connexion
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
delegate:self];
et implémentez la méthode de connexion: willCacheResponse: sur le délégué. Revenir à zéro devrait le faire.
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
J'ai le même problème dans mon application lorsque j'ai demandé des informations à Twitter. Dans mon cas, je n'avais pas besoin de conserver ces informations d'identification, alors je les efface simplement en utilisant le code suivant:
- (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];
}
}
J'espère que ça marche pour quelqu'un :)
Si vous utilisez NSURLConnection, jetez un œil au délégué:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
Valeur de retour
La réponse mise en cache à stocker dans le cache. Le délégué peut renvoyer cachedResponse sans modification, renvoyer une réponse en cache modifiée ou renvoyer nil si aucune réponse en cache ne doit être stockée pour la connexion.
Si ce n'est pas spécifique à une seule demande (vous voulez désactiver le cache pour toute l'application), une seule option est la meilleure.
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];
Si vous utilisez NSURLSession
, une autre solution pour empêcher l'écriture de la demande et des paramètres dans le Cache.db
créé par iOS dans le répertoire Caches
de l'application consiste à définir la variable NSURLCache
pour la configuration de la session sur une mémoire de taille 0 et un cache de disque de taille 0 par exemple.
let configuration = URLSessionConfiguration.default
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)
ou comme mentionné ci-dessus défini au niveau du cache global
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
Vraisemblablement, c'est le 0 pour la taille de disque qui empêche iOS d'écrire sur le disque, mais si vous avez une stratégie de reloadIgnoringLocalCacheData
, la mise en cache de la mémoire ne vous intéressera probablement pas non plus.
Note Ceci empêchera la création de tout dossier Caches/Cache.db
(demandes et réponses) ou Caches/fsCachedData/
(données de réponse). Nous avons décidé d'adopter cette approche dans une application à des fins de sécurité, car nous ne voulons plus que nos demandes soient stockées dans le cache du disque.
Si quelqu'un sait s'il existe un moyen d'arrêter uniquement la mise en cache des demandes mais de conserver la mise en cache des données de réponse à partir du mécanisme de chargement d'URL iOS, cela m'intéresserait. (il n'y a pas d'API ou de documentation officielle à ce sujet d'après ce que je peux dire)
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
En supposant que le serveur soit correctement implémenté, l'insertion de l'en-tête Cache-Control:no-store
dans la demande génèrera une réponse du serveur avec le même en-tête, de sorte que NSURLCache
ne stockera pas les données de réponse sur le disque.
Par conséquent, nul besoin de l’approche simpliste consistant à désactiver la mise en cache du disque NSURLCache
.
PS: l'ajout de l'en-tête devrait fonctionner pour tous les frameworks HTTP, comme AFNetworking