【问题标题】:Xcode static analyser complaining about potential leak when using ARCXcode 静态分析器在使用 ARC 时抱怨潜在的泄漏
【发布时间】:2013-01-29 06:39:50
【问题描述】:

我正在使用 ARC 和 ios sdk 6.0。

我很确定我有一些内存泄漏,我很难追踪。

运行静态分析器后,我收到以下两种方法的警告:

+ (id<MXURLRequest>) requestWithURL:(NSURL*)url {    
  MXASIURLRequest *request = [[MXASIURLRequest alloc] init];

  [request setUrl:url];

  return request; // STATIC ANALYSER: Potential leak of an object stored into 'request' 
}

- (id)parseBody:(NSError *)error {    
  NSString *contentType = [[_request responseHeaders] objectForKey:@"Content-Type"];

  id body = nil;

  if ([contentType hasPrefix:@"application/json"] ||
      [contentType hasPrefix:@"text/json"] ||
      [contentType hasPrefix:@"application/javascript"] ||
      [contentType hasPrefix:@"text/javascript"]) {        
    body = [NSJSONSerialization JSONObjectWithData:[_request responseData] options:NSJSONReadingMutableLeaves error:&error];
  } else if ([contentType hasPrefix:@"image/"] ||
           [contentType hasPrefix:@"audio/"] ||
           [contentType hasPrefix:@"application/octet-stream"]) {        
    body = [_request responseData];
  } else {
    body = [[NSString alloc] initWithData:[_request responseData] encoding:NSUTF8StringEncoding];
  }

  return body; // STATIC ANALYSER : Potential leak of an object stored into 'body'
}

警告如下...

Object leaked: object allocated and stored into 'request' is returned from a method
whose name ('requestWithURL:') does not start with 'copy', 'mutableCopy', 'alloc'
or 'new'.  This violates the naming convention rules given in the Memory Management 
Guide for Cocoa

Object leaked: object allocated and stored into 'body' is returned from a method
whose name ('parseBody:') does not start with 'copy', 'mutableCopy', 'alloc' or
'new'.  This violates the naming convention rules given in the Memory Management
Guide for Cocoa

谁能看到我在这里做错了什么?这些警告是合法的,还是可以忽略?对我来说,这些方法看起来对 ARC 能够处理自动引用计数是有效的。

任何帮助将不胜感激。

【问题讨论】:

  • 您确定您使用的是 ARC 吗?将[request release][body release] 放在那里,看看它是否编译。
  • -autorelease 附加到return request 行。我敢打赌你没有使用 ARC。
  • @WDUK 我 def 使用 ARC,如果我添加发布调用,它不会编译。
  • @CodaFi 你的意思是 __autoreleasing 吗?
  • @Sabobin No. __autoreleasing 通常是为双指针的管理保留的

标签: ios objective-c memory-management automatic-ref-counting


【解决方案1】:

ARC 显然已关闭,无论是对于正在编译到的文件,还是在整个项目中。静态分析器仅在 ARC 关闭时才会抱怨这些东西,因此我将进一步详细说明。

编译器引用的 Cocoa 内存管理指南只允许一组严格的方法在正常情况下从构造函数返回非自动释放的对象(那些是 'init'、'copy'、'mutableCopy' 和 'new') .注意到图案了吗?

因为您在便利构造函数中分配了一个对象,然后将其交给调用者,所以您是拥有它的人,因为您创建了它。 Cocoa 希望你做的是在返回的末尾附加一个自动释放,这样调用者的工作就是保持对新构造对象的引用:

+ (id<MXURLRequest>) requestWithURL:(NSURL*)url {
    MXASIURLRequest *request = [[MXASIURLRequest alloc] init]; +1, we own it

    [request setUrl:url];

    return [request autorelease]; // +0, it's the caller's problem now
}

至于最后一种方法,Cocoa 抱怨你的内存不一致。由于您混合使用构造函数和便利性,该方法有可能返回具有 +1 或 +0 保留计数的对象。举例说明:

- (id)parseBody:(NSError *)error {    
  NSString *contentType = [[_request responseHeaders] objectForKey:@"Content-Type"];

  id body = nil;

  if ([contentType hasPrefix:@"application/json"] ||
      [contentType hasPrefix:@"text/json"] ||
      [contentType hasPrefix:@"application/javascript"] ||
      [contentType hasPrefix:@"text/javascript"]) {        
    body = [NSJSONSerialization JSONObjectWithData:[_request responseData] options:NSJSONReadingMutableLeaves error:&error]; //returns +0
  } else if ([contentType hasPrefix:@"image/"] ||
           [contentType hasPrefix:@"audio/"] ||
           [contentType hasPrefix:@"application/octet-stream"]) {        
    body = [_request responseData]; //potentially returns +1
  } else {
    body = [[NSString alloc] initWithData:[_request responseData] encoding:NSUTF8StringEncoding]; //returns +1
  }

  return body; // STATIC ANALYSER : Potential leak of an object stored into 'body'
}

分析器要求一致性:要么只使用构造函数,要么一致地自动释放。

【讨论】:

  • 非常感谢,你是对的,我错误地关闭了该文件的 arc。为该文件重新打开 ARC 会使警告静音。 +1
  • @Sabobin 没问题。让我抛出关于第二个函数抛出内存警告的最后一个编辑,只是为了迂腐。
猜你喜欢
  • 2021-04-16
  • 2013-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-11
  • 1970-01-01
  • 2012-02-05
相关资源
最近更新 更多