我写了一个测试代码来检查如何使用Instrument(Leaks)。我创建了一个单视图应用程序,点击一个按钮,我就加载了一个新的视图,如下。。。
- (IBAction)btn_clkd:(id)sender {
new_file *new = [[new_file alloc] init];
if (new) {
[self.navigationController pushViewController:new animated:YES];
new = nil;
}
}
在new_file ViewDidLoad方法中,我创建了一个泄漏,如下所示。。。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
char *c_mem = (char*) malloc(10000000);
strcpy(c_mem, "TESTING");
// free(c_mem);
}
即使我在使用ARC,分配的内存也是一个普通的C malloc,并且我在使用后没有释放内存,即使我已经一次又一次地弹出并加载新视图,仪器(Leaks)也没有检测到该代码中的任何泄漏。。。原因是什么,我检查正确吗?
Thanx
如果视图控制器已解除分配(请验证),最终泄漏将检测到c_mem
指针泄漏。
仪器可能无法立即找到,这是由于其用于检测泄漏的算法。
该算法基本上是搜索未引用的变量,这些变量看起来像指向堆的指针。如果发生有一个任意变量,比如p,其值恰好是c_mem
的值,那么Instruments认为指针c_mem
仍然从p引用——即使p可能只包含任意数据而不引用c_mem
。
请注意,Instruments泄漏检测算法实际上更复杂,可能会发生变化并得到改进。
为了找到漏洞,我总是在一个循环中运行特殊的代码,比如单元测试。如果用过的记忆没有及时增长,你通常是好的。您还可以使用Leaks的"快照"功能和Allocations的"标记生成"功能来检查堆的当前状态。
当您弹出ViewController
时,如果没有任何引用,ARC会自动将其与所有变量解除分配。这就是为什么你不会得到泄漏。
使用Leak Instrument查看当您弹出控制器时,控制器会发生什么。你还可以看到上面有很多引用。检测保留循环也很方便。
以下是关于如何使用仪器的完整参考资料。