需要有关 NSString 的帮助
Need assistance regarding NSString
在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];
}
我会发生内存泄漏吗?或者什么?
In 不会泄漏内存,但会获得更多的内存分配,因为不可变副本的新副本与许多时间循环触发器一样 [str stringByAppendingFormat:@"%d", i];
。
当您将数据置于未引用或孤立状态时,将执行内存泄漏,这不会在每次循环时使您的最后一个字符串副本成为孤立的,但会在操作 get 时清除 NSString
的所有副本完成,或 viewDidUnload
.
您的代码在做什么:
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.
pass by copy的意思是得到一个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
因为您传递了一个引用,您实际上可以更改字符串对象的"value",因为您使用的是原始版本而不是副本。
注意
只要您的应用程序存在,字符串文字就会存在。在你的例子中,这意味着你的 NSString *str = @"";
永远不会被释放。所以最后在你循环完你的 for 循环之后,你的内存中有两个字符串对象。它的 @""
您无法再访问它,因为您没有指向它的指针,但它仍然存在!而你的新字符串 str=123456....1000;但这不是内存泄漏。
more information
您不会在示例代码中遇到内存泄漏,因为自动引用计数会检测到对 str 的分配并(自动)释放旧的 str。
但这样做会更好的编码风格(而且几乎肯定会有更好的性能):
NSMutableString* mstr = [NSMutableString new];
for(int i = 0; i < 1000; ++i){
[mstr appendFormat:@"%d",i];
}
NSString* str = mstr;
...
关于第一个问题,我认为这意味着远程进程对可变字符串所做的更改将反映在原始进程的对象中。
不,您的代码不会发生内存泄漏,因为您没有在循环中保留这些对象,它们是使用便捷方法创建的,您不拥有它们,它们将在下一次释放自动释放池的循环。而且,无论您是否使用 ARC 都没有关系,使用便捷方法创建但未保留的对象会在超出其上下文的任何地方被释放。
在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];
}
我会发生内存泄漏吗?或者什么?
In 不会泄漏内存,但会获得更多的内存分配,因为不可变副本的新副本与许多时间循环触发器一样 [str stringByAppendingFormat:@"%d", i];
。
当您将数据置于未引用或孤立状态时,将执行内存泄漏,这不会在每次循环时使您的最后一个字符串副本成为孤立的,但会在操作 get 时清除 NSString
的所有副本完成,或 viewDidUnload
.
您的代码在做什么:
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.
pass by copy的意思是得到一个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
因为您传递了一个引用,您实际上可以更改字符串对象的"value",因为您使用的是原始版本而不是副本。
注意
只要您的应用程序存在,字符串文字就会存在。在你的例子中,这意味着你的 NSString *str = @"";
永远不会被释放。所以最后在你循环完你的 for 循环之后,你的内存中有两个字符串对象。它的 @""
您无法再访问它,因为您没有指向它的指针,但它仍然存在!而你的新字符串 str=123456....1000;但这不是内存泄漏。
more information
您不会在示例代码中遇到内存泄漏,因为自动引用计数会检测到对 str 的分配并(自动)释放旧的 str。
但这样做会更好的编码风格(而且几乎肯定会有更好的性能):
NSMutableString* mstr = [NSMutableString new];
for(int i = 0; i < 1000; ++i){
[mstr appendFormat:@"%d",i];
}
NSString* str = mstr;
...
关于第一个问题,我认为这意味着远程进程对可变字符串所做的更改将反映在原始进程的对象中。
不,您的代码不会发生内存泄漏,因为您没有在循环中保留这些对象,它们是使用便捷方法创建的,您不拥有它们,它们将在下一次释放自动释放池的循环。而且,无论您是否使用 ARC 都没有关系,使用便捷方法创建但未保留的对象会在超出其上下文的任何地方被释放。