内存管理问题

时间:2011-07-19 11:13:10

标签: objective-c

我已经在Objective-C中编程了几个星期了,我认为现在是时候我更多地考虑我的内存管理了,所以我有几个场景我想澄清一下。

NSString *myString = @"Hello, World";

如果我要在下一行做

NSString *anotherString = myString;

它被复制了吗?或者是另一个字符串只是指向myString的指针?如果它只是一个指针,我将如何使anotherString成为具有自己内存的myString的副本?

如果我

怎么办?
[anotherString release];

实际上发布了什么,只是anotherString,还是myString也消失了?

然后,如果我要做

anotherString = nil;

这实际上是释放内存和使用还是仍然分配空内存的空间?显然仍然可以使用指针。它对myString有什么作用?

这将真正帮助我更好地管理内存,而不仅仅是[object release];随机导致崩溃。

非常感谢你回复的任何人。

3 个答案:

答案 0 :(得分:2)

当你这样做时:

NSString *myString = @"Hello, World";
NSString *anotherString = myString;

...你正在创建一个NSString实例,并指向它的两个指针。所以要回答你的问题,不要没有被复制。是的,anotherString只是一个指针,myString也是如此,实际的NSString实例在内存中是关闭的,在两个指针指向的地址处。

要制作字符串的副本,您可以:

NSString *anotherString = [myString copy];

当你这样做时:

[anotherString release];

NSString指向的anotherString实例已发布。 anotherString本身没有任何事情发生。它继续指向您现在无效的对象实例。如果myString指向同一个实例,那么是的,这会导致myString“离开”。

如果你这样做:

anotherString = nil;

...然后你导致内存泄漏,因为你重新分配了指针而没有释放它所指向的东西。除非在这种情况下,因为@"Hello, World"是一个加载到堆栈上的文字值,并且不会被代码保留。

在任何情况下,将anotherString设置为nil都不会对您的字符串产生任何影响,只会更改anotherString指向的内容。您的实际NSString实例仍在内存中,完全没有意识到您只是丢弃了对它的引用(可能的例外:引用计数/垃圾收集环境)。

是的,随机调用[object release]会导致崩溃。作为一般规则,如果符合以下条件,则只应在release上调用{<1}}。

  1. 您在其上调用了allocinit...
  2. 你打电话给retain
  3. 您在某个其他对象上调用copy后获得了该对象。
  4. 请注意这些堆叠,因此,如果您alloc某事,retain,然后copy,则需要对release进行3次调用,其中2次为您alloc编辑的对象,以及副本的对象。

    作为旁注,您可能会发现编写对象声明更清晰,如:

    NSString* myString = @"Hello, World";
    NSString* anotherString = myString;
    

    ...这使得你声明的是指向NSString的指针而不是NSString本身更明显。就个人而言,我认为您的原始语法虽然常用,但也是backwards

答案 1 :(得分:0)

此字符串:

NSString *myString = @"Hello, World";

在堆栈上创建。它在应用程序启动时加载到内存中。您不拥有支持该对象的内存,因此不应该释放它。

如果要将字符串复制到堆(可以管理内存),只需执行以下操作:

NSString *anotherString = [myString copy];

然后,当你完成它时,你负责释放该对象。

[anotherString release];

将指针设置为nil只会清除指针,而不是指向它的对象。它仍在记忆中。

答案 2 :(得分:0)

NSString * anotherString = myString;

---这只是一个指针赋值

---您可以使用[myString copy]

复制myString

[anotherString release];

---您正在发布anotherString的所有者船(请阅读保留计数概念)

anotherString = nil;

---你只是将指针指向任何东西。

我建议请阅读有关内存管理苹果文档的更多信息......