首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSString - stringWithFormat vs stringWithString

NSString - stringWithFormat vs stringWithString
EN

Stack Overflow用户
提问于 2011-02-22 19:48:17
回答 2查看 2.3K关注 0票数 1

我在.m文件中声明了一个全局NSString变量。当我在.m文件中的任意位置使用stringWithFormat为其提供字符串值时,该值在两次函数调用之间不会持久存在。但是,当我使用stringWithString执行相同的操作时,该值在整个实现和任何函数调用中都保持不变,从而使其具有真正的全局行为。换句话说,stringWithFormat和stringWithString在内部的内存管理有什么不同?

当使用stringWithString时,为什么在抛出“消息发送到释放的实例”(在另一个函数中的NSLog语句中,该函数使用stringWithFormat为NSString赋值之后)抛出“消息发送到释放的实例”时,该值仍然存在?当我用stringWithString替换时,没有这样的问题。

谢谢!

编辑:我忘了提到,是的,在stringWithFormat的情况下,当我后来做了一个手动保留时,它是有效的。该值持续存在。这就是问题所在。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-02-22 20:04:00

编译器很聪明,他不是创建几十个不同的NSString实例,它们都具有相同的值,而是创建一个无法释放的实例,而所有其他实例只指向程序中硬编码的NSString。

因为硬编码的NSString永远不会被释放,所以即使在自动释放池已经释放了它之后,你也可以使用它。

这仅仅涵盖了你错误的内存管理。而且你绝对不应该依赖这种行为。

编辑。没什么可说的了。使用stringWithString: NSString创建的字符串将简单地指向文本在内存中的位置。

下面是一个小示例:

代码语言:javascript
复制
NSString *string = @"Foo";
NSLog(@"%@ - %p", string, string);
NSString *string2 = string;
NSLog(@"%@ - %p", string2, string2);
NSString *string3 = [string copy];
NSLog(@"%@ - %p", string3, string3);
NSString *string4 = [string retain];
NSLog(@"%@ - %p", string4, string4);
NSString *string5 = [NSString stringWithString:string];
NSLog(@"%@ - %p", string5, string5);
NSString *string6 = [[NSString alloc] initWithString:string];
NSLog(@"%@ - %p", string6, string6);

您将看到它们都指向相同的地址。

代码语言:javascript
复制
2011-02-22 13:24:41.202 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.204 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.204 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.206 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.206 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.207 xxx[40783:207] Foo - 0x74120

他们所有人都不会被取消分配。因此,您可以从代码中的其他方法访问string5,它仍然指向地址295740,并且NSString "Foo“仍然在那里。

但是没有指向字符串文字的NSString对象将在此时被释放,并且您将得到一个糟糕的访问异常。

您违反了内存管理规则,但是如果您只使用字符串文字,您将永远不会注意到这一点。直到编译器的行为改变。

所以做对了,学习适当的内存管理,不要依赖内部机制。如果以后需要,请保留所有自动释放的对象。即使它们指向字符串文字

票数 2
EN

Stack Overflow用户

发布于 2011-02-22 20:04:11

听起来你没有保留这个字符串,因此当你以后试图访问它的时候,它已经被释放了。如果你不熟悉内存管理,可以看看苹果的Memory Management Programming Guide

-stringWithString:没有中断的原因很可能是因为编译器正在对字符串文字进行一些优化;它查看整个程序并只存储对定义的相同字符串的一个引用。因此,您的指针将在应用程序的整个生命周期中保持有效。

你不应该依赖这一点。你不能保证所有的编译器都会做这种优化。在创建变量时保留它,并在不再需要它时释放它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5077678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档