iPhone:使用 NSOperationQueue 时发生内存泄漏

发布于 2024-08-29 06:27:57 字数 1902 浏览 0 评论 0原文

我在这里坐了至少半个小时才发现我的代码中存在内存泄漏。 我刚刚使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文