为什么仪器“泄漏”模板没有在我的iOS应用程序上发现我的内存泄漏?

时间:2010-07-29 18:17:00

标签: iphone ipad memory-leaks instruments

我正在深入研究iOS开发并熟悉这些工具。在每天结束时,我在我的应用程序上执行“运行仪器工具 - >泄漏”以检查我当天可能实施的任何内存泄漏。它似乎很少发现任何泄漏,虽然我想我只是一个自然的iOS程序员,但我拒绝相信;)

无论如何,我刚刚在我的代码中找到了我认为是内存泄漏的内容,并且它没有被Instruments监视。我有这行代码......

gkSession = [[GKSession alloc] initWithSessionID:@"testID" displayName:@"Temp Display Name" sessionMode:GKSessionModeClient];

我发现我在代码中的任何地方都没有调用release。我的问题是......

  1. 这是内存泄漏吗?
  2. 如果是这样,仪器可能没有抓住它的原因是什么?
  3. 我明显担心的是我的代码中有内存泄漏而且Instruments没有捕获它们。

    非常感谢您的帮助!

2 个答案:

答案 0 :(得分:6)

有多种类型的动态分配内存。

  1. 带引用计数的内存 大于零,仍然被引用并且正在使用中。

  2. 带引用计数的内存     零仍然被引用并仍在使用中。

  3. 引用计数大于零且未引用的内存。

  4. 引用计数为零但未引用的内存。

  5. 带引用计数的内存 大于零仍然被引用且未被使用。

  6. 类型1在使用内存中是正常的。类型2是一个错误,当您尝试遵循该引用时,该错误将被报告为非法访问。类型3是仪器检测到的泄漏类型。类型4应该由内存系统释放。

    类型5是仪器无法检测到的泄漏,也不会被完整的垃圾收集器处理。这就是你似乎拥有的。

    编辑:

    我忘记了类型6 - 内存的引用计数与实际引用的数量不匹配。这最终可能会转变为2型或4型。

答案 1 :(得分:2)

#1的答案是“可能”......如果您的视图控制器从堆栈中弹出,而没有其他人保留它,那么您的视图控制器应该被取消分配。 但是,(这可能是你问题#2的答案)我最初犯的一个错误就是不明白当你调用pushViewController时:导航控制器会保留你的视图控制器,所以你不要不得不。确保在创建视图控制器并将其推入堆栈后释放视图控制器。

MyViewController * viewController = [[MyViewController alloc] init...];
[self.navigationController pushViewController:viewController];
[viewController release];

我相信静态分析仪会在这种情况下忘记释放调用时发出警告......这是静态分析仪如此强大的一个原因。

如果此时释放视图控制器,则保留计数将始终高于应有的+1。

我注意到静态分析仪比仪器的泄漏工具对这些东西更有用。 (例如,它不会找到包含循环引用的“泄漏”......两个引用自身的泄漏对象不会显示,因为“引用”仍然在您的对象周围。)

所以目前你有一些......

@interface MyClass : UIViewController
{
     GKSession * gkSession;
}

...

@end

在您的实现中,您应该确保在dealloc方法中释放iVar:

@implementation MyClass

...

- (void)dealloc
{
     [super dealloc];

     if (gkSession) [gkSession release];
}
@end