iPhone アプリでディスク キャッシュを有効にする代わりに、 Olivier Poitrey の SDURLCache (github リンク) を使用しています。NSURLCache
非常にうまく機能しますがNSHTTPURLResponseInternal
、ディスクにキャッシュされたオブジェクトが返されたときに奇妙なことにリークしています (オブジェクトがメモリから返された場合やオブジェクトが見つからなかった場合はリークしません)。次のコード スニペットは、SDURLCache がディスクからデータを読み取る方法を示しています。
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request
{
NSCachedURLResponse *memoryResponse = [super cachedResponseForRequest:request];
if (memoryResponse)
{
return memoryResponse;
}
NSString *cacheKey = [SDURLCache cacheKeyForURL:request.URL];
// NOTE: We don't handle expiration here as even staled cache data is necessary for NSURLConnection to handle cache revalidation.
// Staled cache data is also needed for cachePolicies which force the use of the cache.
NSMutableDictionary *accesses = [self.diskCacheInfo objectForKey:kSDURLCacheInfoAccessesKey];
if ([accesses objectForKey:cacheKey]) // OPTI: Check for cache-hit in a in-memory dictionnary before to hit the FS
{
NSCachedURLResponse *diskResponse = [NSKeyedUnarchiver unarchiveObjectWithFile:[diskCachePath stringByAppendingPathComponent:cacheKey]];
if (diskResponse)
{
// OPTI: Log the entry last access time for LRU cache eviction algorithm but don't save the dictionary
// on disk now in order to save IO and time
[accesses setObject:[NSDate date] forKey:cacheKey];
diskCacheInfoDirty = YES;
// OPTI: Store the response to memory cache for potential future requests
[super storeCachedResponse:diskResponse forRequest:request];
return diskResponse;
}
}
return nil;
}
各NSHTTPURLResponseInternal
リークのスタック トレースには、SDURLCache
コードへの 2 つの参照が含まれています。
最初のポイントは行[accesses setObject:[NSDate date] forKey:cacheKey];
です。2番目の最新のポイントは次のとおりです。
@implementation NSCachedURLResponse(NSCoder)
- (id)initWithCoder:(NSCoder *)coder
{
return [self initWithResponse:[coder decodeObjectForKey:@"response"]
data:[coder decodeDataObject]
userInfo:[coder decodeObjectForKey:@"userInfo"]
storagePolicy:[coder decodeIntForKey:@"storagePolicy"]];
}
@end
以前にこの問題に遭遇した人はいますか? 解決策について何か考えはありますか?さらにコード サンプルを投稿する必要がある場合はお知らせください。
乾杯。
更新:コードの作者であるOlivier Poitrey からのツイート
NSURLCache の継承を削除し、メモリ キャッシュを処理することを計画しています。これにより、リークが修正される可能性があります。