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
答案 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];