我使用Olivier Poitrey's SDURLCache(github鏈接)作爲NSURLCache
的替代方法,以在iPhone應用程序中啓用磁盤緩存。使用SDURLCache時的內存泄漏(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
代碼。
第一條線指向[accesses setObject:[NSDate date] forKey:cacheKey];
。第二點和最新點如下:
@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
有沒有人遇到過這個問題?對解決方案有任何想法?讓我知道我是否應該發佈更多的代碼示例。
乾杯。
UPDATE:Tweet from Olivier Poitrey,代碼
我打算取出NSURLCache固有和處理內存緩存的作者,它可以修復泄漏