我正在深入研究iOS开发并熟悉这些工具。在每天结束时,我在我的应用程序上执行“运行仪器工具 - >泄漏”以检查我当天可能实施的任何内存泄漏。它似乎很少发现任何泄漏,虽然我想我只是一个自然的iOS程序员,但我拒绝相信;)
无论如何,我刚刚在我的代码中找到了我认为是内存泄漏的内容,并且它没有被Instruments监视。我有这行代码......
gkSession = [[GKSession alloc] initWithSessionID:@"testID" displayName:@"Temp Display Name" sessionMode:GKSessionModeClient];
我发现我在代码中的任何地方都没有调用release
。我的问题是......
我明显担心的是我的代码中有内存泄漏而且Instruments没有捕获它们。
非常感谢您的帮助!
答案 0 :(得分: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