Objective-C NSString的内存管理

时间:2012-05-11 16:11:22

标签: objective-c memory-management

  

可能重复:
  Local variable assign versus direct assign; properties and memory
  Which way is the correct way to allocate memory with a property?

我想知道这两个代码示例之间的区别。

1

NSString *someString = @"Blabla";


{...Some code...}


imageView.title = [[NSString alloc] initWithString:someString];

2:

NSString *someString = @"Blabla";


{...Some code...}


NSString *str = [[NSString alloc] initWithString:someString];
imageView.title = str;
[str release];

由于某些原因,Xcode Analyzer警告我选项#1可能会导致内存泄漏 - 所以当我将代码更改为选项#2时,分析器不会警告我。

有谁知道是什么原因?

非常感谢!

3 个答案:

答案 0 :(得分:1)

假设您没有使用ARC,

[str release];

线是这里的关键。将该行添加到第一个示例代码段的末尾,看看是否收到相同的警告。在对象上显式调用alloc会增加引用计数 - 减少引用计数release应该被调用。

有关ARC的信息,请参阅:How does the new automatic reference counting mechanism work?

答案 1 :(得分:0)

在第一个示例中,您分配了一个新的NSString,将其传递,但​​未释放它。您负责释放该字符串,该字符串在您第一次分配时具有+1保留计数。

(忽略这样一个事实,即您的简单示例可能不会导致实际泄漏。但这不是重点,这仍然不是管理内存的正确方法)

答案 2 :(得分:0)

第一个例子中的问题:

NSString *someString = @"Blabla";
{...Some code...}
imageView.title = [[NSString alloc] initWithString:someString];

是你通过alloc / init分配一个字符串并将其分配给imageView.title属性retain。实际上,alloc会给你一个保留计数为1的对象;将它分配给retain属性也会增加其保留计数(2)。现在,当最终取消分配imageView时,其dealloc方法将释放title属性(从而将其保留计数减1),但由于您无法调用{{}},因此不会释放该对象。 {1}}再次平衡您自己的release

这里要注意的重要一点是你要分配给alloc财产;如果retain不是保留属性,那么您的代码就可以了。

这是您修复第一个示例的方法:

title

imageView.title = [[[NSString alloc] initWithString:someString] autorelease];

依赖于使用商品构造函数,按照惯例为您提供自动释放的对象。

(在你的第二个例子中你的方式也是正确的,虽然稍微冗长一点)。