我已经在Objective-C中编程了几个星期了,我认为现在是时候我更多地考虑我的内存管理了,所以我有几个场景我想澄清一下。
NSString *myString = @"Hello, World";
如果我要在下一行做
NSString *anotherString = myString;
它被复制了吗?或者是另一个字符串只是指向myString的指针?如果它只是一个指针,我将如何使anotherString成为具有自己内存的myString的副本?
如果我
怎么办?[anotherString release];
实际上发布了什么,只是anotherString,还是myString也消失了?
然后,如果我要做
anotherString = nil;
这实际上是释放内存和使用还是仍然分配空内存的空间?显然仍然可以使用指针。它对myString有什么作用?
这将真正帮助我更好地管理内存,而不仅仅是[object release];
随机导致崩溃。
非常感谢你回复的任何人。
答案 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}}。
alloc
和init...
。retain
。copy
后获得了该对象。请注意这些堆叠,因此,如果您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;
---你只是将指针指向任何东西。
我建议请阅读有关内存管理苹果文档的更多信息......