对象潜在泄漏警告 - 需要澄清
在我分析我的代码后,Xcode 指出了潜在的泄漏,如下所示。
这是我应该关心的事情吗?
在此代码中,设置 doublyLinkedList 的类是唯一的所有者,并在整个程序执行过程中继续管理该对象。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
在我分析我的代码后,Xcode 指出了潜在的泄漏,如下所示。
这是我应该关心的事情吗?
在此代码中,设置 doublyLinkedList 的类是唯一的所有者,并在整个程序执行过程中继续管理该对象。
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
接受
或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
发布评论
评论(4)
您收到警告的原因是因为
new
调用返回一个保留对象,然后您的 setter 可能会对其执行另一个retain
(取决于它是合成的还是手动生成)。另外,我建议您使用标准的
alloc
/init
而不是new
,这样两阶段创建就很明显了。这更好:
或者只是
The reason you're getting the warning is because the
new
call returns a retained object, and then your setter is probably doing anotherretain
on it (depends on whether it's synthesized or manually generated).Also, I would recommend you use the standard
alloc
/init
instead ofnew
, so that the two-phase creation is obvious.This is better:
or just
您可能希望这样做:
在标头中,将 doublyLinkedList 声明为保留的
@property
。You may wish to do this instead:
In the header, declare doublyLinkedList a
@property
that is retained.您有“潜在泄漏”,因为分析器发现您已经为
DoublyLinkedList
实例分配了内存(使用new
),将其放入名为dll 的局部变量中
,并且没有在同一范围内释放该内存。假设您设置的
doublyLinkedList
成员碰巧也是声明为retain
ing 的属性,那么您也会遇到实际泄漏,因为您过度保留了在此处创建的DoublyLinkedList
。所有权规则表示您对此实例拥有一项声明,因为您调用了
new
来创建它。当您将实例传递给setDoublyLinkedList:
时,它会被保留,然后您就有两个声明。当init
方法结束时,您只有一个通过 ivar/property 对该实例的引用——您已经丢失了局部变量——这意味着您拥有的所有权声明多于您拥有的引用。这是一个很好的迹象,表明您将发生泄漏。要修复泄漏,您需要在
init
方法结束之前放弃您的声明之一。您可以通过以下两种方式之一执行此操作:设置属性后立即使用release
:或
autorelease
:但是,应该注意的是,在
中使用 setter init
可能有问题(另请参阅Mike Ash 的文章主题),因为访问器可能(可能)产生副作用,这取决于您的对象是否已完全设置。关于这个问题似乎有两个阵营,最好阅读它并得出自己的结论,但您可能会发现它简化了分配给 ivars 而不是使用属性的初始化方法:这在术语上是完全正确的的内存管理。
最后,如果
DoublyLinkedList
是一个您拥有其代码的类,您还可以考虑编写一个方便的构造函数,它将为您返回一个新的自动释放实例。 Cocoa 中的约定是简单地在类之后命名方法,使用标准方法名称大小写,如下所示:请注意,这是一个类方法:
并参见 我对“自分配对象”的回答以解释这些构造函数。
You have a "potential leak" because the Analyzer sees that you have allocated memory for a
DoublyLinkedList
instance (usingnew
), put it into a local variable calleddll
, and not released that memory in the same scope.Assuming that the
doublyLinkedList
member that you're setting happens to also be a property declared asretain
ing, you also have an actual leak, because you have over-retained theDoublyLinkedList
that you create here.The ownership rules say that you have one claim on this instance because you called
new
to create it. When you pass the instance tosetDoublyLinkedList:
, it is retained, and you then have two claims. When theinit
method ends, you only have one reference to the instance, through the ivar/property -- you've lost the local variable -- which means that you have more ownership claims than you have references. This is a good indication that you will have a leak.To fix the leak, you need to relinquish one of your claims before the end of the
init
method. You can do this in one of two ways, usingrelease
as soon as the property is set:or
autorelease
:However, it should be noted that using setters in
init
may be problematic (see also Mike Ash's writeup on the topic), because accessors can -- potentially -- have side effects that depend on your object already being fully set up. There seem to be two camps on this issue, and it's probably best to read about it and come to your own conclusions, but you may find that it simplifies your initializer methods to assign to ivars rather than using properties:This is completely correct in terms of memory management.
Finally, if
DoublyLinkedList
is a class whose code you have, you can also consider writing a convenience constructor, which will return a new, autoreleased instance for you. The convention in Cocoa is to simply name the method after the class, with standard method name casing, like so:Note that this is a class method:
and see my answer to "Self-allocating objects" for an explanation of these constructors.
如果您有一个名为“doublyLinkedList”的属性(基于给定代码的假设),并且它是“保留的”,您可以执行以下操作:
If you have a property called "doublyLinkedList" (assumption based on code given), and it is "retained," you can do the following: