ARC 从方法最佳实践返回对象(收到内存泄漏警告)
我正在 xcode 4.2 中创建一个示例项目,并注意到新项目是使用 ARC 设置的。
我有一个如下所示的方法。以前,我会在方法中自动释放单元格,并让调用者的表视图保留该单元格。使用ARC,自动释放是不可能的,
- (UITableViewCell*) getCellForIndex:(int)index {
UITableViewCell *cell =
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
if (index == 0)
cell.textLabel.text = profileToUse.name;
if (index == 1)
cell.textLabel.text = profileToUse.sex;
if (index == 2)
cell.textLabel.text = profileToUse.city;
return cell;
}
当我在上面的代码上运行分析工具时,它说对象“cell”存在潜在的内存泄漏。
使用 ARC 应该如何编写上述内容才能消除分析警告?我做错了什么?
谢谢。
I was creating a sample project in xcode 4.2 and noticed that the new project was setup with ARC.
I have a method shown below. Previously, I would have autoreleased the cell in the method and let the caller's table view retain the cell. With ARC, autoreleasing would not be possible,
- (UITableViewCell*) getCellForIndex:(int)index {
UITableViewCell *cell =
[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
if (index == 0)
cell.textLabel.text = profileToUse.name;
if (index == 1)
cell.textLabel.text = profileToUse.sex;
if (index == 2)
cell.textLabel.text = profileToUse.city;
return cell;
}
When I running the analyze tool on the code above, it says that there is a potential memory leak of the object 'cell'.
How should the above be written using ARC so that the analyze warning will go away? What am I doing wrong?
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
尝试将方法重命名为 -cellForIndex:,以“get”为前缀的方法在 Cocoa 中具有不同的隐含行为。
(另外,也许 -cellAtIndex:为了与 NSArray 保持一致,等等......)
Try renaming the method to -cellForIndex:, "get"-prefixed methods have different implied behavior in Cocoa.
(Also, maybe -cellAtIndex: for consistency with NSArray, etc...)
您的方法
getCellForIndex:
分配并返回一个对象,这样它类似于直接的alloc
(实际上您的代码只是一个alloc
,一些初始化)。由于 ARC 在调用时看不到方法的实际实现,因此它必须对返回对象的所有权做出假设,并且该假设是所有权未转移。当编译你的实现时,ARC 注意到你的代码违反了这个假设并警告你。
通过在
@interface
和@implementation
中向您的方法添加显式属性,可以覆盖该假设:ARC 现在将知道对象所有权已转移。
alloc
、new
等系列中的方法会自动添加此属性。正如其他回复建议您最好重命名您的方法,newCellForIndex:
在这里可能更合适,因为new
用于alloc
和init
这就是你的方法所做的事情。顺便说一句:改变你的第二个和第二个第三个
if
到else if
会让你的算法更清晰(并且稍微快一点,但这不是这样做的原因)。评论中的问题:
ARC确实引入了新属性等,但也使用推理和默认值,因此如果您遵循正常的Cocoa约定,您不应该太频繁地需要它们 - 当然是YMMV...除了Apple的文档你可以找到描述此处。
Your method
getCellForIndex:
allocates and returns an object, in this way it is similar to a straightalloc
(indeed your code is just analloc
with some initialization).As ARC does not see the actual implementation of a method when calling it must make an assumption about ownership of the returned object, and that assumption is that ownership is not transferred. When compiling your implementation ARC notices that your code violates this assumption and warns you.
The assumption can be overridden by adding an explicit attribute to your method in both the
@interface
and@implementation
:ARC will now know the object ownership is transferred. Methods in the
alloc
,new
etc. families have this attribute added automatically. As other replies suggest you might be better off renaming your method,newCellForIndex:
might be appropriate here asnew
is used for a combination ofalloc
andinit
which is what your method does.BTW: Changing your second & third
if
's toelse if
's would make your algorithm clearer (and slightly faster, but that is not the reason to do it).Question in comment:
ARC does introduce new attributes etc. but also uses inference and defaults so that if you follow normal Cocoa conventions you shouldn't need them too often - YMMV of course... In addition to Apple's docs you can find a description here.