2013-12-16 3 views
3

Я хотел бы реализовать шаблон наблюдателя с помощью Delphi. Интерфейс ISubject и класс TWeatherData, который реализует наблюдателя.delphi AV в шаблоне наблюдателя с интерфейсами

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. 

ответ

5

Ставится AV, потому что вы единственный магазин указатель на IObserver. Но это слабое упоминание, и Observer-Instance уже исчезло.

Вместо этого следует использовать TList<IObserver>, как показано на странице Nicks blog.

Если вы не хотите дженериков, то вы должны использовать TInterfaceList, как показано here