保留和释放 nsstring
Retain and release nsstring
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
您需要进行正常的内存管理:
if (![[str substringFromIndex:str.length-1] isEqualToString:@"\n"])
{
NSString *newStr = [str stringByAppendingString:@"\n"];
[str release];
str = [newStr retain];
}
请记住,stringByAppendingString:
returns 是一个自动释放的字符串(它还会创建一个全新的字符串)。
建议一:使用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 调用 return 保留计数为 1 的对象)
然后 属性 再次保留它。
那段代码应该这样写:
self.str = [[NSString alloc] initWithFormat: @"number %d", value] autorelease];
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
您需要进行正常的内存管理:
if (![[str substringFromIndex:str.length-1] isEqualToString:@"\n"])
{
NSString *newStr = [str stringByAppendingString:@"\n"];
[str release];
str = [newStr retain];
}
请记住,stringByAppendingString:
returns 是一个自动释放的字符串(它还会创建一个全新的字符串)。
建议一:使用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 调用 return 保留计数为 1 的对象)
然后 属性 再次保留它。
那段代码应该这样写:
self.str = [[NSString alloc] initWithFormat: @"number %d", value] autorelease];