这里的观察者实现是否存在内存泄漏?

3
也许我不是很了解Delphi,但我想问一下:
在这个网站上:http://blogs.teamb.com/joannacarter/2004/06/30/690,我发现了一个基于接口的观察者模式实现。
当进行attach操作时,会调用以下内容:
procedure TSubject.Attach(Observer: IObserver);
begin
    if fObservers = nil then
      fObservers := TInterfaceList.Create;
    fObservers.Add(AObserver);
    Notify;
end;

在detach中,它有以下代码
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;
2个回答

6
不应该这样做,因为正如Bharat所说,IInterface会处理它。需要注意的是,在您参考的示例中,fObservers声明为IInterfaceList。它是一个接口。在Delphi中,接口变量类似于C++中的智能指针,它们会自动调用_Assign和_Release。
如果fObservers被声明为TInterfaceList,那么它将是一个对象,对象在赋值时不会执行任何特殊操作,因此调用Free是正确的。

2
如果fObservers被声明为TInterfaceList,则+1适用于备注。 - The_Fox

5
不需要添加fObservers.Free;语句。 IInterface 将负责添加和释放 fObservers
Delphi 使用 _AddRef 和 _Release 来管理接口对象的生命周期。
当你将接口引用分配给接口变量时,Delphi 自动调用 _AddRef
当变量超出作用域时,Delphi 自动调用 _Release
有关更多信息,请查看此链接

哇,它有垃圾回收器?为什么他们不把它实现到所有地方呢? - none
2
Delphi不是一种完全的垃圾回收语言,用户定义的类型应该手动分配和释放。它仅为一些内置类型(如字符串、动态数组和接口)提供自动回收以方便使用。 - Bharat
2
通过广泛使用接口,您可以获得类似于垃圾回收的结果。这意味着所有类都需要实现至少一个接口:TMyClass = class(TInterfacedObject, IMyInterface)...并且所有引用应该是接口引用:MyObject: IMyInterface。请注意,循环引用可能会导致引用计数出现问题。 - Kenneth Cochran
3
由于Delphi的对象模型较早,比Delphi接口实现(如COM)还要早,因此它采用了类似于COM这样实现接口的引用计数方式,而不是垃圾收集。在Delphi 1和2发布之后,ActiveX才开始流行起来,所以Delphi团队无法负担重写VCL/RTL以完全基于接口(就像微软从未因同样的原因为MFC进行过这样的操作)。另外,与垃圾收集相比,引用计数也存在问题。关于这个问题请提出一个新问题。 - Jeroen Wiert Pluimers
1
哇,尽管有缺点,引用计数确实被认为是垃圾回收(http://en.wikipedia.org/wiki/Reference_counting);今天我学到了新东西,谢谢!我认为你的“实现不好”的说法太苛刻了;引用计数失败的原因通常是因为程序员干预机制(通过故意添加/删除引用或通过将接口与手动释放的对象混合使用)。这也是在Delphi之外的COM世界中存在许多问题的原因:遵循引用计数规则对很多人来说很难。 - Jeroen Wiert Pluimers
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接