iOS内存管理:ivars,static和NSStrings

时间:2010-09-03 19:55:51

标签: iphone objective-c

我设法让自己对内存管理的一些元素感到困惑。我是Objective-c和内存管理语言的新手。

我已经阅读了内存管理指南,但我仍然对一些事情感到困惑。 1)是否需要清理任何对象未保留的ivars和方法变量。例如

-(void) someMethod{
int count = 100;
 for (int i=0; i <count;  i++) {
  NSLog(@"Count = %d", i);
 }
    }    

方法完成后“count”var会发生什么? 如果一个方法分配了很多临时变量,只要它们没有发布,就会从内存中删除那些临时变量,分配对象?或者我是否需要以某种方式将它们设置为零?

2)如果我有一个静态变量,例如一个NSString,那么当该类被解除分配时,我是否必须做任何事情才能从内存中删除?

3)我注意到NSStrings似乎有一个2147483647的retainCount,维基百科告诉我这是32位有符号整数的最大值。

http://en.wikipedia.org/wiki/2147483647

myString retainCount = 2147483647

-(void) someMethod{
NSString *myString = @"testString";
NSLog(@"myString retainCount = %d", [myString retainCount]);
// logs:  myString retainCount = 2147483647
}

方法结束时会发生什么?这个记忆是否会被清空?任何东西都没有引用该字符串。我的理解是NSString的@“”方便方法返回一个自动释放的对象,但是最后还是使用retainCount为2147483647来自动释放某些东西?在这种情况下,保留或释放任何NSString的意义何在?

我很清楚retainCount应该被忽略,但这只是让我不知道这里发生了什么。

4)这有关系吗?我知道与NSString相关的内存并不多,但我想成为一名优秀的内存管理公民,而且我对最佳实践比其他任何事情都更感兴趣。

3 个答案:

答案 0 :(得分:5)

仅保留/释放对象,而不是int,bool,float,double或其他内置函数。因此,将它用于id或其他包含指向对象的指针的类。在您的示例中,不需要保留或释放计数。它在堆栈上分配,在函数返回时自动清理。

您需要处理alloc的任何本地对象。这些是在retainCount设置为1的情况下创建的,因此您需要保留它们以供日后使用或释放​​它们。大多数Cocoa函数(不以copy或alloc开头)返回一个自动释放的对象。这意味着他们将在稍后调用它们 - 如果你在它们上面调用retain,你只能在函数之后保存它们。如果你想要清理它们,你不需要做任何事情(调用release会导致释放调用太多)。

如果有一个指向对象的静态变量,那么当该类的对象被解除分配时,它不会被触及。如果您希望它被释放,您必须在其上调用release。如果static是int,bool或其他内置函数,则不能(不能)调用它上面的release。这是应用程序全局记忆的一部分。

设置为字符串文字的NSStrings不应该调用它们的版本。 retainCount对他们来说毫无意义。对于signed int值,该值也为-1。

如果你这样做 - [[NSString alloc] initCallHere:etc] - 你必须在其上发布释放。大多数时候你得到字符串,你不使用alloc,所以你不需要调用release。如果你保留一个,你需要打电话给释放。

是的,这很重要。随着时间的推移,泄漏将导致iPhone杀死您的应用程序。

答案 1 :(得分:2)

  1. 您无需担心count因为它是整数,原始数据类型,而不是对象。

  2. 我已经读过那些只是在应用程序终止或你明确发布它们时就会消失。

  3. 你是对的,你应该以这种方式担心保留计数。 Cocoa自动为@""NSConstantString个对象提供绝对最高保留值,以便它们不能被解除分配。

  4. 你的主题过于复杂。 指南的要点是,您知道在三种特定情况下您只需要担心内存管理。 Apple为您提供了这些指导原则,以便人们不必担心每个类的特定内部(例如手动跟踪retainCount),更不用说Cocoa有时会做出不同的处理(与NSConstantString一样) )。只要你记住这些指导原则,你真的不必知道下面发生的事情的细节(当然,对保留计数概念的理解有所帮助,但将其与手动跟踪它进行比较)。

  5. 我不知道您具体阅读哪个指南,但如果您没有尝试this one,我强烈推荐它。它以简洁直接的方式总结了这三条准则。

答案 2 :(得分:2)

Cocoa内存管理规则仅涵盖Objective C对象。

当任何子程序或方法退出时,局部变量(非静态)被清除(实际上堆栈存储器只是被同一线程中的后续子程序或方法重用/覆盖)。当应用程序在退出后被操作系统拆除时,需要清除需要内存(字符串)和静态变量的常量。手动释放时,手动清理malloc内存。

但是你分配或保留的任何对象:(无论是分配给ivar,本地,全局,静态等)都必须像任何其他对象一样进行管理。小心地将对象分配给全局变量,除非您真的擅长保留计数管理。