2011-10-05 53 views
1

下面的代码如预期的那样工作,清理没有僵尸的东西。此方法存在的类是节点的所有者,正在发布,但在“分析”时出现以下两个问题。不正确的递减错误,代码审查

如果可能,你能帮我理解为什么吗?

enter image description here

- (void) dealloc { 
    NSLog(@"Releasing [Doubly Linked List] .. "); 

    Node *thisNode = [self firstNode]; 
    Node *nextNode = [thisNode next]; 

    while (nextNode != nil) { 

     // If "Next node" is not nil, it means that 
     // "previous node" can now be released 

     NSLog(@" - releasing node \"%c\"", [[nextNode previous] charData]); 
     [[nextNode previous] release]; 

     nextNode = [nextNode next]; 
    } 

    [[self lastNode] release]; 
    [super dealloc]; 
} 

回答

1

单击该消息左侧的图标,它会显示通过产生错误的代码路径。

你正在发布一些你不拥有的东西,[nextNode previous]。特别是你没有分配或保留它,也没有从一个以新的或复制开始的方法获得它,所以你没有它的所有权,也不应该释放它。

发布不属于您的课程的东西也很少见,[[nextNode previous] release]

现在:[[self lastNode] release];
如上所述,您没有获得您要发布的对象的所有权。

如果lastNode是一个保留的属性,那么您正在破坏setter,并且之后通过setter将值赋给lastNode时,对象上将会有额外的释放并且可能会崩溃。如果它不再是一个属性,那么释放由方法调用返回的东西就非常不标准。

任何版本的[[self lastNode] release]代码都是非标准的,如果被避免,将会减少所有权(保留/发布)问题。

通过研究Apple内存管理文档,您将节省大量时间和悲伤。

+0

'nextNode'在类中定义,但通过'properties'。这是班级的局部变量。每个节点“知道”前方和后方的内容。类拥有所有节点。 '[nextNode previous]'本身就是'Node *' – JAM

+0

如果previous是一个属性,那么释放它的正确方法是'self.previous = nil;'。不过,我怀疑这是否是这种情况。 – zaph

1

问题在于你没有按照Objective C的普通内存管理约定做事,静态分析器变得混乱。基本上,分配对象的Objective C类“拥有”对象并负责释放它。在这里,你没有使用这些约定,所以分析仪抱怨,即使你在做什么工作正常。

有关ownership的更多信息,请参阅Apple文档。

+0

你能建议如何解决这个问题吗? – JAM

+0

是在同一个类中分配一个新节点还是在其他地方分配?我认为让分析器弄清楚你在做什么可能有点棘手,但是......因为它并不真正希望你创建自己的数据结构。 –