3

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 の継​​承を削除し、メモリ キャッシュを処理することを計画しています。これにより、リークが修正される可能性があります。

4

1 に答える 1

1

それ自体が答えではなく、むしろ意識です。iOS 5.0 以降の NSURLCache は、デフォルトでフラッシュと RAM の両方にキャッシュするようになりました。したがって、オンディスク キャッシュを取得するために SDURLCache を使用していて、5.0 以降をターゲットにしている場合、SDURLCache を使用する理由はありません。

于 2012-04-20T17:14:50.210 に答える