iPhone:使用 NSOperationQueue 时发生内存泄漏
我在这里坐了至少半个小时才发现我的代码中存在内存泄漏。 我刚刚使用 NSOperationQueue 将对(触摸)方法的同步调用替换为异步调用。 在我更改代码后,泄漏检查器报告内存泄漏。 使用 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;
}
当然,触摸方法也没有什么特别的。只需更改文件的日期即可。
-(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];
}
}
I'm sitting here for at least half an hour to find a memory leak in my code.
I just replaced an synchronous call to a (touch) method with an asynchronous one using NSOperationQueue.
The Leak Inspector reports a memory leak after I did the change to the code.
What's wrong with the version using NSOperationQueue?
Version without a 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;
}
Version with a MemoryLeak (I do not see any)
-(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;
}
And of course, the touch method does nothing special too. Just change the date of the file.
-(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];
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论