在我分析了我的代码之后,Xcode表明了潜在的泄漏,如下所示。
这是我应该关注的吗?
在此代码中,设置doublyLinkedList
的类是唯一所有者,并在程序执行期间继续管理此对象。
答案 0 :(得分:3)
您收到警告的原因是new
调用返回一个保留对象,然后您的setter可能正在对其执行另一个retain
(取决于它是合成还是手动生成)
此外,我建议您使用标准alloc
/ init
代替new
,以便创建两阶段。
这样更好:
if (self) {
DoublyLinkedList *dll = [[[DoublyLinkedList alloc] init] autorelease];
self.doublyLinkedList = dll;
}
或只是
if (self) {
self.doublyLinkedList = [[[DoublyLinkedList alloc] init] autorelease];
}
答案 1 :(得分:1)
您可能希望这样做:
if (self) {
DoublyLinkedList *dll = [DoublyLinkedList new];
self.doublyLinkedList = dll;
[dll release];
}
在标题中,声明doublelyLinkedList保留的@property
。
答案 2 :(得分:1)
您有“潜在泄漏”,因为分析器发现您已为DoublyLinkedList
实例分配内存(使用new
),将其放入名为dll
的本地变量中,并且没有释放相同范围的内存。
假设您正在设置的doublyLinkedList
成员也是声明为retain
的属性,那么您还有实际泄漏,因为您已经结束 - 获取您在此处创建的DoublyLinkedList
。
ownership rules表示您对此实例有一项声明,因为您致电new
来创建它。当您将实例传递给setDoublyLinkedList:
时,它会被保留,然后您有两个声明。当init
方法结束时,您只有一个对实例的引用,通过ivar / property - 您丢失了本地变量 - 这意味着您拥有的所有权声明多于您引用的所有权声明。这是一个很好的迹象表明你会有泄漏。
要修复泄漏,您需要在init
方法结束前放弃其中一项声明。您可以通过以下两种方式之一完成此操作:设置属性后立即使用release
:
DoublyLinkedList * dll = [DoublyLinkedList new];
[self setDoublyLinkedList:dll];
[dll release];
或autorelease
:
[self setDoublyLinkedList:[[DoublyLinkedList new] autorelease]];
// Or equivalent procedures involving a temp variable
但是,应该注意使用init
may be problematic中的setter(另请参阅Mike Ash's writeup on the topic),因为访问者可能 - 可能 - 具有依赖于您的对象的副作用完全成立。在这个问题上似乎有两个阵营,最好阅读它并得出你自己的结论,但你可能会发现它简化了初始化方法以分配给ivars而不是使用属性:
if( self ){
doublyLinkedList = [DoublyLinkedList new];
}
这在内存管理方面完全正确。
最后,如果DoublyLinkedList
是您拥有代码的类,您还可以考虑编写一个方便构造函数,它将为您返回一个新的自动释放实例。 Cocoa中的约定是在类之后简单地命名方法,使用标准方法名称大小写,如下所示:
+ (id) doublyLinkedList {
return [[[self alloc] init] autorelease];
}
请注意,这是一种类方法:
if( self ){
[self setDoublyLinkedList:[DoublyLinkedList doublyLinkedList]];
}
并查看my answer to "Self-allocating objects"以获取有关这些构造函数的说明。
答案 3 :(得分:0)
如果您有一个名为“doublyLinkedList”的属性(基于给定代码的假设),并且“保留”,您可以执行以下操作:
if (self) {
DoublyLinkedList *dll = [[DoublyLinkedList alloc] init]
self.doublyLinkedList = dll;
[dll release];
}