带有接口的观察者模式中的delphi AV

Ulr*_*nin 3 delphi access-violation delphi-xe observer-pattern

我想用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;
Run Code Online (Sandbox Code Playgroud)

我得到一个访问冲突有关的读取地址的时候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;
Run Code Online (Sandbox Code Playgroud)

主要方案:

    weatherStation := TWeatherData.Create;
    currentConditionalDisplay := TCurrentConditionalDisplay.Create(weatherStation);
    weatherStation.setMeasurements(100.0, 58.0, 756.0); // a stack head of exception.
Run Code Online (Sandbox Code Playgroud)

Sir*_*ufo 5

AV被引发,因为你只存储指针IObserver.但这是一个弱引用,Observer-Instance已经消失了.

使用TList<IObserver>替代如图尼克斯博客.

如果你不希望泛型那么你应该使用TInterfaceList如图所示这里