Question

I am using Olivier Poitrey's SDURLCache (github link) as an alternative to NSURLCache to enable disk-caching in an iPhone app.

It works very well but is curiously leaking a NSHTTPURLResponseInternal when a disk cached object is returned (no leak when object is returned from memory or no object found). The following code snippet shows how SDURLCache reads the data from the disk:

- (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;
}

The stack trace for each of the NSHTTPURLResponseInternal leaks contains two references to the SDURLCache code.

The first points to the line [accesses setObject:[NSDate date] forKey:cacheKey];. The second, and latest points to the following:

@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 

Has anyone encountered this problem before? Any thoughts on a solution? Let me know if I should post more code samples.

Cheers.

UPDATE: Tweet from Olivier Poitrey, the author of the code

I'm planning on removing the NSURLCache inherency and handle the memory cache, it may fix the leak

Was it helpful?

Solution

Not an answer per se, but rather, awareness. NSURLCache on iOS 5.0 and above now caches to both flash and RAM by default. Thus, if you were using SDURLCache in order to obtain on-disk caching, and are targeting 5.0 and above, then there's no reason to use SDURLCache.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top