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

时间:2009-01-01 16:58:30

标签: cocoa-touch caching

在iPhone上,我使用NSURLRequest为一大块数据执行HTTP请求。对象分配峰值,我相应地分配数据。当我完成数据后,我会相应地将其释放 - 但是仪器没有显示任何已释放的数据!

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

有没有办法在请求后清除此缓存或阻止任何数据首先被缓存?

我尝试过使用下面记录的所有缓存策略:

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

但似乎没有任何东西可以释放记忆!

6 个答案:

答案 0 :(得分:153)

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

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

然后创建连接

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

并在委托上实现connection:willCacheResponse:方法。只要返回零就应该这样做。

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

答案 1 :(得分: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];
    }
}

我希望它适用于某人:)

答案 2 :(得分:10)

如果您使用NSURLConnection,请查看委托:

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

返回值

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

答案 3 :(得分:7)

如果不是特定于单个请求(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];

答案 4 :(得分:7)

如果您正在使用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或官方文档)

答案 5 :(得分:0)

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

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

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

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