-2

可能重复:
局部变量分配与直接分配;属性和内存
哪种方式是使用属性分配内存的正确方法?

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

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 时,分析器不会警告我。

有谁知道这是什么原因?

非常感谢!

4

3 回答 3

1

假设您没有使用 ARC,则

[str release];

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

有关 ARC 的信息,请参阅:新的自动引用计数机制如何工作?

于 2012-05-11T16:22:52.460 回答
0

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

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

于 2012-05-11T16:14:30.613 回答
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),但对象不会被释放,因为您没有机会release再次调用来平衡自己的alloc.

这里要注意的重要一点是您正在分配一个retain属性;不是title保留属性,您的代码就可以了。

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

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

或者

imageView.title = [NSString stringWithString:someString];

which relies on the use of a commodity constructor which gives you an autoreleased object by convention.

(it is also correct the way you do it in your second example, though slightly more verbose).

于 2012-05-11T16:30:08.650 回答