在NSString NSString Class Reference中这意味着什么
Distributed objects:
Over distributed-object connections, mutable string objects are passed by-reference and immutable string objects are passed by-copy.
并且NSString无法更改,因此当我在此代码中更改str
时会发生什么
NSString *str = @"";
for (int i=0; i<1000; i++) {
str = [str stringByAppendingFormat:@"%d", i];
}
我会得到内存泄漏吗?或者是什么?
答案 0 :(得分:1)
您的代码正在做什么:
NSString *str = @""; // pointer str points at memory address 123 for example
for (int i=0; i<1000; i++) {
// now you don't change the value to which the pointer str points
// instead you create a new string located at address, lets say, 900 and let the pointer str know to point at address 900 instead of 123
str = [str stringByAppendingFormat:@"%d", i]; // this method creates a new string and returns a pointer to the new string!
// you can't do this because str is immutable
// [str appendString:@"mmmm"];
}
Mutable意味着您可以更改NSString。例如,使用appendString。
传递副本意味着您获得了NSString的副本,您可以随心所欲地执行任何操作;它不会改变原来的NSString
- (void)magic:(NSString *)string
{
string = @"LOL";
NSLog(@"%@", string);
}
// somewhere in your code
NSString *s = @"Hello";
NSLog(@"%@", s); // prints hello
[self magic:s]; // prints LOL
NSLog(@"%@", s); // prints hello not lol
但是想象你得到一个可变的NSString。
- (void)magic2:(NSMutableString *)string
{
[string appendString:@".COM"];
}
// somewhere in your code
NSString *s = @"Hello";
NSMutableString *m = [s mutableCopy];
NSLog(@"%@", m); // prints hello
[self magic2:m];
NSLog(@"%@", m); // prints hello.COM
因为传递参考,您实际上可以更改&#34;值&#34;您正在使用原始版本而不是重复的字符串对象。
注意强>
只要您的应用程序存在,字符串文字就会存在。在您的例子中,这意味着您的NSString *str = @"";
永远不会被取消分配。因此,在循环完for循环之后,最后有两个字符串对象存在于您的记忆中。它的@""
你不能再访问了,因为你没有它的指针,但它仍然存在!你的新字符串str = 123456 .... 1000;但这不是内存泄漏。
答案 1 :(得分:1)
不,你不会因为代码而导致内存泄漏,因为你没有在循环中保留这些对象,它们是通过便利方法创建的,你不拥有它们,它们将被释放在下一个自动释放池周期。并且,如果您使用ARC,则无关紧要,使用便捷方法创建且未保留的对象将在不在其上下文的任何位置发布。
答案 2 :(得分:0)
In不会泄漏内存,但会获得更多的内存分配,因为将不可变副本的新副本作为多个时间循环触发[str stringByAppendingFormat:@"%d", i];
。
当您将数据置于未引用状态或孤立时,将执行内存泄漏,这不会在每次循环时生成字符串孤立的最后一个副本,但在操作完成时将清除NSString
的所有副本,或viewDidUnload
。
答案 3 :(得分:0)
示例代码中不会出现内存泄漏,因为自动引用计数将检测到str的赋值并(自动)释放旧的str。
但要做到这一点会有更好的编码风格(几乎肯定会有更好的性能):
NSMutableString* mstr = [NSMutableString new];
for(int i = 0; i < 1000; ++i){
[mstr appendFormat:@"%d",i];
}
NSString* str = mstr;
...
关于第一个问题,我认为这意味着远程进程对可变字符串所做的更改将反映在原始进程的对象中。