我知道NSString的所有实例都是不可变的。如果为字符串分配新值,则会解决新内存,旧字符串将丢失。
但是如果使用NSMutableString,无论你做什么,字符串都会在内存中保持相同的地址。
我想知道这究竟是如何运作的。使用像replaceCharactersInRange这样的方法,我甚至可以为字符串添加更多字符,因此我需要更多内存用于字符串。内存中跟随字符串的对象会发生什么?它们都被重新安置并放在内存中吗?我不这么认为。但究竟发生了什么?
答案 0 :(得分:11)
我知道NSString的所有实例都是 inmutable。如果您指定了新值 一个字符串新的内存被解决 旧字符串将会丢失。
这不是可变性的工作原理,也不是NSStrings的引用是如何工作的。指针也不起作用。
指向对象的指针 - NSString *a;
声明一个变量a
,它是一个指向对象的指针 - 只是将地址保存在对象的内存中。实际对象[通常]是包含实际对象本身的内存堆上的分配。
在这些术语中,运行时间确实没有区别:
NSString *a;
NSMutableString *b;
两者都引用 - 内存中的某些分配地址。唯一的区别是在编译期间,b
将被视为与a
不同,如果您在调用NSMutableString
时使用b
方法,则编译器不会抱怨(但是会在调用a
)时使用。
就NSMutableString
如何工作而言,它在内部包含一个包含字符串数据的缓冲区(或几个缓冲区 - 实现细节)。当您调用其中一个改变字符串内容的方法时,可变字符串将根据需要重新分配其内部存储以包含新数据。
对象不会在内存中移动。一旦分配,分配将永远不会移动 - 对象或分配的地址永远不会改变。唯一的例外是当您使用realloc()
之类的东西时可能会返回不同的地址。但是,这实际上只是free(); malloc(); memcpy();
的序列。
我建议您重新访问Objective-C Programming Guide或者可能是C编程手册。
答案 1 :(得分:0)
NSMutableString就像C ++ std :: string do一样。我不确切知道它们是如何工作的,但有两种流行的方法:
您创建一个包含两个变量的结构。一个字符和一个指针。 当一个新的char(或更多)被添加时,你创建一个新的struct实例,并将地址添加到字符串的最后一个struct实例。这样你就有了一堆结构,指针指向下一个结构。
大多数新手的方式。不是最坏的,但可能是最慢的。
你保存一个“正常”不可变的字符串。如果添加了一个新的字符,则在内存中分配一个区域,其大小为旧字符串+1,复制旧字符串并连接新字符。这是一个非常简单的方法,不是吗?
一个更高级的版本是创建一个大小为+50的新字符串,并在最后添加字符和一个新的null
,不要忘记覆盖旧的null
。通过这种方式,对于具有大量更改的字符串,它会更有效。
正如我之前所说,我不知道std :: string或NSMutableString是如何解决这个问题的。但这些是最常见的方式。