コード内のメモリ リークを見つけるために、少なくとも 30 分間ここに座っています。NSOperationQueue を使用して、(タッチ) メソッドへの同期呼び出しを非同期呼び出しに置き換えました。コードに変更を加えた後、Leak Inspector がメモリ リークを報告します。NSOperationQueue を使用するバージョンの何が問題になっていますか?
MemoryLeak のないバージョン
-(NSData *)dataForKey:(NSString*)ressourceId_
{
NSString *cacheKey = [self cacheKeyForRessource:ressourceId_]; // returns an autoreleased NSString*
NSString *path = [self cachePathForKey:cacheKey]; // returns an autoreleased NSString*
NSData *data = [[self memoryCache] objectForKey:cacheKey];
if (!data)
{
data = [self loadData:path]; // returns an autoreleased NSData*
if (data)
{
[[self memoryCache] setObject:data forKey:cacheKey];
}
}
[[self touch:path];
return data;
}
MemoryLeak のあるバージョン (何も表示されません)
-(NSData *)dataForKey:(NSString*)ressourceId_
{
NSString *cacheKey = [self cacheKeyForRessource:ressourceId_]; // returns an autoreleased NSString*
NSString *path = [self cachePathForKey:cacheKey]; // returns an autoreleased NSString*
NSData *data = [[self memoryCache] objectForKey:cacheKey];
if (!data)
{
data = [self loadData:path]; // returns an autoreleased NSData*
if (data)
{
[[self memoryCache] setObject:data forKey:cacheKey];
}
}
NSInvocationOperation *touchOp = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(touch:) object:path];
[[self operationQueue] addOperation:touchOp];
[touchOp release];
return data;
}
もちろん、 touch メソッドも特別なことは何もしません。ファイルの日付を変更するだけです。
-(void)touch:(id)path_
{
NSString *path = (NSString *)path_;
NSFileManager *fm = [NSFileManager defaultManager];
if ([fm fileExistsAtPath:path])
{
NSDictionary *attributes = [NSDictionary dictionaryWithObjectsAndKeys:[NSDate date], NSFileModificationDate, nil];
[fm setAttributes: attributes ofItemAtPath:path error:nil];
}
}