On iPhone, I perform a HTTP request using NSURLRequest for a chunk of data. Object allocation spikes and I assign the data accordingly. When I finish with the data, I free it up accordingly - however instruments doesn't show any data to have been freed!
在iPhone上,我使用NSURLRequest对一大块数据执行HTTP请求。对象分配峰值,我相应地分配数据。当我完成数据后,我会相应地释放它 - 但是仪器没有显示任何已释放的数据!
My theory is that by default HTTP requests are cached, however - I don't want my iPhone app to cache this data.
我的理论是默认情况下HTTP请求被缓存,但是 - 我不希望我的iPhone应用程序缓存这些数据。
Is there a way to clear this cache after a request or prevent any data from being cached in the first place?
有没有办法在请求后清除此缓存或阻止任何数据首先被缓存?
I've tried using all the cache policies documented a little like below:
我尝试过使用下面记录的所有缓存策略:
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]];
theRequest.cachePolicy = NSURLRequestReloadIgnoringLocalCacheData;
but nothing seems to free up the memory!
但似乎没有什么可以释放记忆!
6 个解决方案
#1
Usually it's easier to create the request like this
通常,更容易创建这样的请求
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0];
Then create the connection
然后创建连接
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
delegate:self];
and implement the connection:willCacheResponse: method on the delegate. Just returning nil should do it.
并在委托上实现连接:willCacheResponse:方法。刚刚返回nil应该这样做。
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
#2
I have the same problem in my app when I requested info from twitter. In my case I didn't need to preserve those credentials, so I simple erase them using the next code:
当我从twitter请求信息时,我在我的应用程序中遇到了同样的问题。在我的情况下,我不需要保留这些凭据,所以我使用下一个代码简单地擦除它们:
- (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];
}
}
I hope it works for somebody :)
我希望它适用于某人:)
#3
If you use NSURLConnection take a look at the delegate:
如果您使用NSURLConnection,请查看委托:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
Return Value
The actual cached response to store in the cache. The delegate may return cachedResponse unmodified, return a modified cached response, or return nil if no cached response should be stored for the connection.
存储在缓存中的实际缓存响应。委托可以不修改返回cachedResponse,返回修改后的缓存响应,如果没有为连接存储缓存响应,则返回nil。
#4
If not specific to a single request(U want disable cache for whole app) below one is the best option.Add this code in app delegate or based on ur need any where
如果不是特定于单个请求(U想要禁用整个应用程序的缓存),则一个是最佳选项。在app delegate中添加此代码或根据您的需要任何地方
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];
#5
If you're using NSURLSession
, another solution to prevent request and parameters being written to the Cache.db
iOS creates within the app's Caches
directory, is to set the NSURLCache
for the session's configuration to a 0 size memory and 0 size disk cache e.g.
如果你正在使用NSURLSession,另一个防止写入Cache.db iOS的请求和参数的解决方案是在应用程序的Caches目录中创建的,那就是将会话配置的NSURLCache设置为0大小的内存和0大小的磁盘缓存,例如:
let configuration = URLSessionConfiguration.default
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)
or as mentioned above set at a global cache level
或者如上所述设置在全局缓存级别
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
Presumably it's the 0 for disk size that stops iOS writing to disk but if you have a policy to reloadIgnoringLocalCacheData
then you probably aren't interested in memory caching either.
据推测,磁盘大小为0会阻止iOS写入磁盘,但如果您有重新加载IgnoringLocalCacheData的策略,那么您可能对内存缓存也不感兴趣。
Note This will prevent any Caches/Cache.db
(requests & responses) or Caches/fsCachedData/
folder (response data) being created at all. We've decided to take this approach in an app for security purposes as we don't want our requests to be stored on disk cache ever.
注意这将阻止任何Caches / Cache.db(请求和响应)或Caches / fsCachedData /文件夹(响应数据)的创建。出于安全考虑,我们决定在应用程序中采用这种方法,因为我们不希望我们的请求永远存储在磁盘缓存中。
If anyone knows is there's a way to stop only request caching but keep response data caching from the iOS URL Loading mechanism, I'd be interested to know. (there's no API or official documentation about this from what I can tell)
如果有人知道有一种方法可以停止请求缓存但是保持从iOS URL加载机制缓存响应数据,我有兴趣知道。 (根据我的判断,没有关于此的API或官方文档)
#6
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
Assuming the server is correctly implemented, putting the Cache-Control:no-store
header in the request will generate a server response with the same header, thus causing NSURLCache
to not store the response data on disk.
假设服务器已正确实现,请在请求中放置Cache-Control:no-store标头将生成具有相同标头的服务器响应,从而导致NSURLCache不将响应数据存储在磁盘上。
Therefore, no need for the shotgun approach of disabling NSURLCache
disk caching.
因此,不需要禁用NSURLCache磁盘缓存的鸟枪方法。
PS: Adding the header should work for all HTTP frameworks, like AFNetworking
PS:添加标头应适用于所有HTTP框架,如AFNetworking
#1
Usually it's easier to create the request like this
通常,更容易创建这样的请求
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringCacheData
timeoutInterval:60.0];
Then create the connection
然后创建连接
NSURLConnection *conn = [NSURLConnection connectionWithRequest:request
delegate:self];
and implement the connection:willCacheResponse: method on the delegate. Just returning nil should do it.
并在委托上实现连接:willCacheResponse:方法。刚刚返回nil应该这样做。
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
return nil;
}
#2
I have the same problem in my app when I requested info from twitter. In my case I didn't need to preserve those credentials, so I simple erase them using the next code:
当我从twitter请求信息时,我在我的应用程序中遇到了同样的问题。在我的情况下,我不需要保留这些凭据,所以我使用下一个代码简单地擦除它们:
- (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];
}
}
I hope it works for somebody :)
我希望它适用于某人:)
#3
If you use NSURLConnection take a look at the delegate:
如果您使用NSURLConnection,请查看委托:
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse
Return Value
The actual cached response to store in the cache. The delegate may return cachedResponse unmodified, return a modified cached response, or return nil if no cached response should be stored for the connection.
存储在缓存中的实际缓存响应。委托可以不修改返回cachedResponse,返回修改后的缓存响应,如果没有为连接存储缓存响应,则返回nil。
#4
If not specific to a single request(U want disable cache for whole app) below one is the best option.Add this code in app delegate or based on ur need any where
如果不是特定于单个请求(U想要禁用整个应用程序的缓存),则一个是最佳选项。在app delegate中添加此代码或根据您的需要任何地方
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];
#5
If you're using NSURLSession
, another solution to prevent request and parameters being written to the Cache.db
iOS creates within the app's Caches
directory, is to set the NSURLCache
for the session's configuration to a 0 size memory and 0 size disk cache e.g.
如果你正在使用NSURLSession,另一个防止写入Cache.db iOS的请求和参数的解决方案是在应用程序的Caches目录中创建的,那就是将会话配置的NSURLCache设置为0大小的内存和0大小的磁盘缓存,例如:
let configuration = URLSessionConfiguration.default
configuration.urlCache = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
let session = URLSession(configuration: configuration)
or as mentioned above set at a global cache level
或者如上所述设置在全局缓存级别
URLCache.shared = URLCache(memoryCapacity: 0, diskCapacity: 0, diskPath: nil)
Presumably it's the 0 for disk size that stops iOS writing to disk but if you have a policy to reloadIgnoringLocalCacheData
then you probably aren't interested in memory caching either.
据推测,磁盘大小为0会阻止iOS写入磁盘,但如果您有重新加载IgnoringLocalCacheData的策略,那么您可能对内存缓存也不感兴趣。
Note This will prevent any Caches/Cache.db
(requests & responses) or Caches/fsCachedData/
folder (response data) being created at all. We've decided to take this approach in an app for security purposes as we don't want our requests to be stored on disk cache ever.
注意这将阻止任何Caches / Cache.db(请求和响应)或Caches / fsCachedData /文件夹(响应数据)的创建。出于安全考虑,我们决定在应用程序中采用这种方法,因为我们不希望我们的请求永远存储在磁盘缓存中。
If anyone knows is there's a way to stop only request caching but keep response data caching from the iOS URL Loading mechanism, I'd be interested to know. (there's no API or official documentation about this from what I can tell)
如果有人知道有一种方法可以停止请求缓存但是保持从iOS URL加载机制缓存响应数据,我有兴趣知道。 (根据我的判断,没有关于此的API或官方文档)
#6
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] url];
[request setValue:@"no-store" forHTTPHeaderField:@"Cache-Control"];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
Assuming the server is correctly implemented, putting the Cache-Control:no-store
header in the request will generate a server response with the same header, thus causing NSURLCache
to not store the response data on disk.
假设服务器已正确实现,请在请求中放置Cache-Control:no-store标头将生成具有相同标头的服务器响应,从而导致NSURLCache不将响应数据存储在磁盘上。
Therefore, no need for the shotgun approach of disabling NSURLCache
disk caching.
因此,不需要禁用NSURLCache磁盘缓存的鸟枪方法。
PS: Adding the header should work for all HTTP frameworks, like AFNetworking
PS:添加标头应适用于所有HTTP框架,如AFNetworking