2010-10-27 34 views
3

也许我不知道德尔福那么好,但是我想问问你:这里的观察者实现是否有内存泄漏?

在这个网站:http://blogs.teamb.com/joannacarter/2004/06/30/690我发现观察者模式的基础上iterface的implemetation。

做连接的时候,有一个这样的电话:

procedure TSubject.Attach(Observer: IObserver); 
begin 
    if fObservers = nil then 
     fObservers := TInterfaceList.Create; 
    fObservers.Add(AObserver); 
    Notify; 
end; 

,并在分离它的代码

procedure TSubject.Detach(Observer: IObserver); 
begin 
    if fObservers <> nil then 
    begin 
     fObservers.Remove(AObserver); 
     if fObservers.Count = 0 then 
     fObservers := nil; 
    end; 
end; 

它应该是:

procedure TSubject.Detach(Observer: IObserver); 
begin 
    if fObservers <> nil then 
    begin 
     fObservers.Remove(AObserver); 
     if fObservers.Count = 0 then begin 
     fObservers.Free; 
     fObservers := nil; 
     end; 
    end; 
end; 

回答

5

有无需添加fObservers.Free;声明。 IInterface将负责添加和释放fObservers

Delphi使用_AddRef and _Release来管理接口对象的生存期。

将接口引用分配给接口变量时,Delphi自动调用_AddRef

当变量超出范围时,Delphi自动调用_Release

欲了解更多信息,请通过this link

+0

OMG它有一个垃圾回收器?他们为什么没有全部实施呢? – none 2010-10-27 13:15:59

+2

Delphi不是一个完整的垃圾收集语言,用户定义的类型应该手动分配和释放。它只提供一些内置类型的自动收集,例如字符串,动态数组和接口,以方便使用。 – Bharat 2010-10-27 13:32:58

+2

@none通过自由使用接口,您可以获得类似的垃圾收集结果。这意味着你所有的类都需要实现至少一个接口:TMyClass = class(TInterfacedObject,IMyInterface)...并且所有引用都应该是接口引用:MyObject:IMyInterface。请注意,循环引用可能会引起引用计数问题。 – 2010-10-27 13:59:02

6

不,不应该,因为巴拉特说,IInterface会照顾到这一点。请注意,在您正在使用的示例中,fObservers被声明为IInterfaceList。这是一个界面。 Delphi中的接口变量类似于C++中的智能指针,它们自动调用_Addref和_Release。

如果fObservers被声明为TInterfaceList,另一方面,它将是一个对象,并且对象在赋值时没有做任何特殊的事情,所以调用Free是正确的。

+2

注释+1如果fObservers被声明为TInterfaceList *。 – 2010-10-27 13:51:33