静态分析器停止检测未发布的分配

时间:2012-01-03 18:20:25

标签: xcode4 memory-leaks static-analysis

我使用的是Xcode 4.这是一个巨大的内存泄漏,我认为这是最简单的静态分析器之一:

-(void)leak:(id)sender{
 images=[[NSMutableArray alloc] init];
 for (int i=0; i<=2000; i++) { 
     UIImage *image=[[UIImage alloc] initWithContentsOfFile:[[NSBundle   
 mainBundle]pathForResource:@"Icon" ofType:@"png"]];
     [images addObject: image];
 }
}

但是当我选择Product | Analyze时,分析仪没有捕捉到任何东西。我是否对Xcode进行了任何意外更改?或者这是真的应该是这样吗?

1 个答案:

答案 0 :(得分:0)

好的,这是我在尝试了很多变种之后得到的。在上面的代码中,在问题中,我分配了一个图像,然后我将保留计数为+1的图像放到图像数组中,而图像数组又保留了图像,从而导致保留计数为+2。理想情况下,我必须在将图像对象添加到数组后释放它。但我没有,这是一个明显的内存泄漏。但奇怪的静态分析仪无法捕捉到这种泄漏。  现在,这是抓住了。代码在for循环中。如果我将它放在循环外,分析仪会检测到它。所以我认为这与编译优化相关,并没有注意到循环中的危险。

这是另一个问题。虽然分析仪可以检测到泄漏,但如果我在仪器上进行测试,仍然无法检测到泄漏。也很奇怪,不是吗?好的,这就是原因。这是因为如果有任何对象的引用,乐器不会显示泄漏。所以我给你两个案例进行比较:

  images=[[NSMutableArray alloc] init]; 
  UIImage *image=[[UIImage alloc] initWithContentsOfFile:[[NSBundle   
  mainBundle]pathForResource:@"Icon" ofType:@"png"]];
  [images addObject: image];

这样静态分析器将捕获内存泄漏(注意代码不在循环内)。但这些工具不会。但是,如果我再添加一行代码:

  images=[[NSMutableArray alloc] init]; 
  UIImage *image=[[UIImage alloc] initWithContentsOfFile:[[NSBundle   
  mainBundle]pathForResource:@"Icon" ofType:@"png"]];
  [images addObject: image];

  [images release];

然后没有对象拥有图像对象,所以它会浮动。这样仪器也会检测到泄漏。

我知道上面的情况在现实世界的应用程序中几乎是不可能的,但是出于演示目的的例子,这样你就不会感到困惑。

P.S。我实际上并没有尝试禁用编译优化(如果它存在偏离。)。但我看过一个视频,静态分析仪也会检测到循环内存泄漏。如果你有兴趣,去搜索它。