使用接口在观察者模式中实现Delphi AV

3

我希望使用Delphi实现观察者模式。

这里有一个接口ISubject和一个实现观察者的类TWeatherData

ISubject = interface
    procedure notifyObservers;
    procedure removeObserver(o: IObserver);
    procedure registerObserver(o: IObserver);
  end;

TWeatherData = class(TInterfacedObject, ISubject)
  private
    observers: TList;
    FTemperature: Double;
    FHumidity: Double;
    FPressure: Double;
  public
    // ...
    procedure notifyObservers;
    procedure setMeasurements(ATemperature, AHumidity, APressure: Double);
  end;

当执行TWeatherData.notifyObservers时,我遇到了一个关于读取地址访问冲突

procedure TWeatherData.notifyObservers;
var
  observer: ^IObserver;
begin
  for observer in observers do
    observer.Update(FTemperature, FHumidity, FPressure); //oops -> there raised AV.
end;


procedure TWeatherData.setMeasurements(ATemperature, AHumidity,
  APressure: Double);
begin
  measurementsChanged; // and this one calls TWeatherData.notifyObservers;
end;

主程序如下:
    weatherStation := TWeatherData.Create;
    currentConditionalDisplay := TCurrentConditionalDisplay.Create(weatherStation);
    weatherStation.setMeasurements(100.0, 58.0, 756.0); // a stack head of exception.
1个回答

5

AV出现了,因为你只存储了一个指向IObserver的指针。但这是一个弱引用,Observer实例已经消失了。

应该使用一个TList<IObserver>,如Nick的博客所示。

如果您不想使用泛型,那么可以像这里一样使用TInterfaceList


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