是否可以防止NSURLRequest缓存数据或在请求后删除缓存的数据?


89

在iPhone上,我使用NSURLRequest对大量数据执行HTTP请求。对象分配高峰,我相应地分配数据。完成数据处理后,我会相应地释放它-但是仪器不会显示任何已释放的数据!

我的理论是默认情况下会缓存HTTP请求,但是-我不希望我的iPhone应用程序缓存此数据。

有没有一种方法可以在请求后清除此缓存,或者首先阻止任何数据缓存?

我试过使用所有记录的缓存策略,如下所示:

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

但是似乎没有什么可以释放内存!


可能与缓存不相关吗?您是否尝试过检查数据以查看是否应该重新加载的数据实际上是旧数据?也许您的韭菜来自其他地方。您如何初始化和释放NSURLRequests?这可能有助于诊断问题。
lpfavreau,2009年

仅供参考-如果您想通过暴力删除文件,请在此处执行示例代码:salesforce.stackexchange.com/a/69736
zekel 2016年

Answers:


157

通常,这样创建请求更容易

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

然后创建连接

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

并在委托上实现connection:willCacheResponse:方法。只要返回nil即可。

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

非常感谢您的帮助!缺口。
Nick Cartwright

1
感谢您的想法-我反复调用这样的SOAP Web服务,即使泄漏未显示出任何错误,它也无法控制地增加堆。我花了几天的时间进行优化,最终尝试阻止缓存,因为内部框架中的许多CFURL *对象都在徘徊。从willCacheResponse返回nil是唯一有效的方法!
布朗·戴维斯

15
为什么必须同时执行NSURLRequestReloadIgnoringCacheData 实施connection:willCacheResponse:

1
嗨,我可以使用它来加载本地内容吗?以上是用于NSUrlConnection的,但是我正在使用NSUrlRequest将本地HTML数据加载到UIWebView中。我需要拒绝任何缓存,因为有图像从SQLite进入Web视图,并且每次页面加载时内存都在增加。谢谢。
吉姆,

7
@fabb,覆盖connection:willCacheResponse:允许您不将响应存储在缓存中。NSURLRequestReloadIgnoringCacheData指定连接应在不检查缓存的情况下加载请求。前者大概可以帮助管理内存分配。
Christopher Pickslay 2011年

12

当我从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];
    }
}

我希望它对某人有用:)


对于我的问题,这是一个完美的解决方案,因为凭据已存储并由NSURLConnection自动提交,所以我有重新登录的问题,这非常感谢我的帮助:)
RVN

谢谢您的工作,非常感谢您的建议。其实我的问题是NSURLRequest存储用户名和密码。因此,这有助于从缓存中删除用户凭据...
Nilesh Kikani 2012年

10

如果使用NSURLConnection,请看一下委托:

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

返回值

实际的缓存响应存储在缓存中。委托可以返回未修改的cachedResponse,返回修改后的缓存响应,或者如果没有为该连接存储任何缓存响应,则返回nil。


非常感谢。我的应用程序的内存占用突然减少了一半!缺口。
Nick Cartwright

9

如果您使用NSURLSession,另一种防止Cache.db在应用程序Caches目录中创建的将请求和参数写入iOS的解决方案是将会话NSURLCache配置的设置为0大小的内存和0大小的磁盘缓存,例如

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

或如上所述在全局缓存级别设置

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

大概是磁盘大小0阻止了iOS写入磁盘,但是如果您有相应的政策,reloadIgnoringLocalCacheData那么您可能也不会对内存缓存感兴趣。

注意这将完全阻止创建任何Caches/Cache.db(请求和响应)或Caches/fsCachedData/文件夹(响应数据)。为了安全起见,我们决定在应用程序中采用这种方法,因为我们不希望将请求存储在磁盘缓存中。

如果有人知道有一种方法可以仅停止请求缓存,但保留来自iOS URL加载机制的响应数据缓存,我很想知道。(据我所知,没有API或官方文档)


7

如果不是特定于单个请求(U要禁用整个应用程序的缓存),则最好是以下方法。在应用程序委托中或根据您的需要在任何地方添加此代码

        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
对我来说效果很好,但是您只能使用0而不是进行最终以0结尾的乘法。
加里·里奇斯

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

假设服务器已正确实现,则将Cache-Control:no-store标头放入请求中将生成具有相同标头的服务器响应,从而导致NSURLCache未将响应数据存储在磁盘上。

因此,不需要散弹枪方法来禁用NSURLCache磁盘缓存。

PS:添加标头应适用于所有HTTP框架,例如 AFNetworking

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.