保留并释放nsstring

时间:2015-03-05 19:29:42

标签: objective-c release retain

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

2 个答案:

答案 0 :(得分:4)

您需要进行正常的内存管理:

if (![[str substringFromIndex:str.length-1] isEqualToString:@"\n"])
{
    NSString *newStr = [str stringByAppendingString:@"\n"];
    [str release];
    str = [newStr retain];
}

请记住stringByAppendingString:返回一个自动释放的字符串(它还会创建一个全新的字符串)。

答案 1 :(得分: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"];
}

执行此操作时,属性的setter会在为属性指定新值之前释放str属性中的旧对象。

但请注意,将对象分配给保留属性会增加其保留计数。这会造成泄漏:

self.str = [NSString alloc] initWithFormat: @"number %d", value];

(因为所有alloc / init调用都返回retain-count为1的对象)

然后财产再次保留。

该代码应该这样写:

self.str = [[NSString alloc] initWithFormat: @"number %d", value] autorelease];