保留和释放 nsstring
Posted
技术标签:
【中文标题】保留和释放 nsstring【英文标题】:Retain and release nsstring 【发布时间】:2015-03-05 19:29:41 【问题描述】:str
是我拥有的 NSString。释放它是我的责任,
因为我打电话给initWithString:
if (![[str substringFromIndex:str.length-1] isEqualToString:@"\n"])
str = [str stringByAppendingString:@"\n"];
如果 if 语句中的行到达,我将失去 str
var 的所有权。
所以当我稍后释放str
时,我的应用会因僵尸实例而崩溃:
[str release];
如果 if 语句为 NO(false),则一切正常。
我可以做些什么来保持str的所有权?
请注意,str
可能会很长,我不想初始化另一个 NSString
【问题讨论】:
仅供参考 - 调用stringByAppendingString:
会执行 init
一个全新的字符串。
真的吗? :) 但也许旧字符串会在 :) 之前被释放?
@rmaddy 你有什么建议?
请问您为什么不使用ARC?现在是 2015 年。除非你真的不得不这样做,否则不要让你的生活变得更艰难。
“你有什么建议?” 使用 ARC。 Xcode 使转换变得容易。
【参考方案1】:
你需要做正常的内存管理:
if (![[str substringFromIndex:str.length-1] isEqualToString:@"\n"])
NSString *newStr = [str stringByAppendingString:@"\n"];
[str release];
str = [newStr retain];
请记住,stringByAppendingString:
返回一个自动释放的字符串(它还会创建一个全新的字符串)。
【讨论】:
无论如何都不能在不创建新 srt 的情况下向 str 添加新行 只有一种方法——使用NSMutableString
。【参考方案2】:
建议 1:使用 ARC。它为您解决了这些问题。这是迄今为止最好的解决方案。
正如 rmaddy 所说,Xcode 有一个用于将应用程序转换为 ARC 的自动化工具。查看编辑菜单,在重构>转换为 Objective-C ARC 下。这个过程相当轻松。它会标记自己无法解决的问题(通常只有几件事。)在清理完这些问题后,您就可以关闭并运行,再也不用担心保留计数了。
建议 1a:按照@rmaddy 的建议,将 str 设为可变字符串。
那么您的代码将如下所示:
[str appendString:@"\n"];
这更简单、更容易阅读、更节省内存,并且在 ARC 和手动引用计数中的工作方式完全相同。
如果不这样做,将 str 更改为保留属性
@property (nonatomic, retain) NSString *str);
然后使用属性表示法:
if (![[self.str substringFromIndex: self.str.length-1] isEqualToString:@"\n"])
self.str = [self.str stringByAppendingString:@"\n"];
当您这样做时,属性的设置器会在为属性分配新值之前释放 str 属性中的旧对象。
但请注意,将对象分配给保留属性会增加其保留计数。这会造成泄漏:
self.str = [NSString alloc] initWithFormat: @"number %d", value];
(因为所有 alloc/init 调用都返回保留计数为 1 的对象)
然后该属性再次保留它。
那段代码应该这样写:
self.str = [[NSString alloc] initWithFormat: @"number %d", value] autorelease];
【讨论】:
以上是关于保留和释放 nsstring的主要内容,如果未能解决你的问题,请参考以下文章
有人能告诉我在objective-c中保留和释放到底做了啥吗?
如何在 iPhone / iPad 的应用程序中正确使用保留和释放