Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

EExternalException.. [XP]


Страницы:   1 2

pathfinder ©   (2007-11-09 11:10:00) 

Добрый день.
Есть форма на которой edit и label. При изменении значения в edit-e оно должно меняться и label-е. Попытался сделать это с помощью шаблона Наблюдатель. Взял его реализацию из BDS2006. В методе NotifyObservers возникает EEXternalException при попытке вызвать метод Update элемента списка. Подскажите пожалуйста, в чем моя ошибка?

Код самой программы:
var
 ProgParams: TProgParams;
 ProgView: TProgView;
begin
 ProgParams := TProgParams.Create;
 ProgView := TProgView.Create(ProgParams);
 ProgView.Show;
end.

Реализация классов:
type
 TSubject = class;

 IObserver = interface
   procedure Update(ASubject :TSubject);
 end;

 TSubject = class
 strict private var
   FObservers:TList;
 strict protected
   procedure NotifyObservers;
 public
   constructor Create;
   procedure Attach(AObserver :IObserver);
   procedure Detach(AObserver :IObserver);
 end;

 TProgParams = class(TSubject)
 strict private
   FTest: string;
 public
   function GetParam(const Name: string): string;
   procedure SetParam(const Name: string);
 end;

 TProgView = class(TInterfacedObject, IObserver)
 strict private
   FSubject: TProgParams;
   FViewForm: TViewForm;

   procedure Refresh;
   procedure OnSetParam(Sender: TObject);
 public
   constructor Create(ASubject: TProgParams);
   destructor Destroy;

   procedure Show;

   procedure Update(ASubject :TSubject);
 end;

implementation

constructor TSubject.Create;
begin
 inherited Create;
 FObservers := TList.Create;
end;

procedure TSubject.Attach(AObserver :IObserver);
begin
 FObservers.Add(@AObserver);
end;

procedure TSubject.Detach(AObserver :IObserver);
var
 idx :Integer;
begin
 idx := FObservers.IndexOf(@AObserver);
 If idx <> -1 Then
 begin
   FObservers.Delete(idx);
 end;
end;

procedure TSubject.NotifyObservers;
var
 Current :^IObserver;
begin
 for Current in FObservers do
   Current.Update(self);
end;

constructor TProgView.Create(ASubject: TProgParams);
begin
 FSubject := ASubject;
 FSubject.Attach(self);
 FViewForm := TViewForm.Create(nil);
 FViewForm.edtTest.OnChange := OnSetParam;
end;

destructor TProgView.Destroy;
begin
 FSubject.Detach(self);
 FViewForm.Free;
end;

procedure TProgView.OnSetParam(Sender: TObject);
begin
 FSubject.SetParam(FViewForm.edtTest.Text);
end;

procedure TProgView.Refresh;
var
 s: string;
begin
 s := FSubject.GetParam('');
 FViewForm.edtTest.Text := s;
 FViewForm.lblTest.Caption := s;
end;

procedure TProgView.Show;
begin
 FViewForm.ShowModal;
end;

procedure TProgView.Update(ASubject :TSubject);
begin
 Refresh;
end;

{ TProgParams }

function TProgParams.GetParam(const Name: string): string;
begin
 Result := FTest;
end;

procedure TProgParams.SetParam(const Name: string);
begin
 FTest := Name;
 NotifyObservers;
end;


pathfinder   (2007-11-09 13:46:00) [1]


> Сергей М. ©   (09.11.07 13:01) [16]
>
> Или приводи явно интерфейсный тип к указательному.


Воспользовался вашим советом и все заработало:)

Всем спасибо!


pathfinder   (2007-11-09 13:37:00) [2]


> Так что вопрос к тебе в [12] вполне резонен.


Это готовая реализация этого шаблона из делфи. Получается они неправильно сделали?


Сергей М.   (2007-11-09 13:31:00) [3]


> если FObservers.Add(@AObserver); то все ок


С т.з. компилятора - да.
А с т.з. происходящего при этом в ран-тайм - это полная фигня, о чем тебе и сообщает возникшее при этом исключение.

Так что вопрос к тебе в [12] вполне резонен.


pathfinder   (2007-11-09 13:19:00) [4]


> Как же нормально, если при компиляции процитированных тобой
> в [15] строк компилятором обнаружена тобой же процитированная
> ошибка ?
>


Это если так FObservers.Add(AObserver);

А если FObservers.Add(@AObserver); то все ок.


Сергей М.   (2007-11-09 13:14:00) [5]


> здесь то вроде все нормально


Как же нормально, если при компиляции процитированных тобой в [15] строк компилятором обнаружена тобой же процитированная ошибка ?


pathfinder   (2007-11-09 13:07:00) [6]


> Сергей М. ©   (09.11.07 13:01) [16]
>
>
> > pathfinder ©   (09.11.07 12:57) [15]
>
>
> Ну так сделай FObservers типа TInterfaceList, бо на то этот
> тип и предназначен.
> Или приводи явно интерфейсный тип к указательному.


Так здесь то вроде все нормально..

Ошибка здесь:
TSubject.NotifyObservers;
Current.Update(self);


pathfinder   (2007-11-09 13:05:00) [7]


> Конечно, надо делать более реальную задачу.


Не хотелось браться за сложное, если даже с простым не получается.


Anatoly Podgoretsky   (2007-11-09 13:04:00) [8]

> pathfinder  (09.11.2007 12:57:14)  [14]

Конечно, надо делать более реальную задачу.


Сергей М.   (2007-11-09 13:01:00) [9]


> pathfinder ©   (09.11.07 12:57) [15]


Ну так сделай FObservers типа TInterfaceList, бо на то этот тип и предназначен.
Или приводи явноинтерфейсный тип к указательному.


pathfinder   (2007-11-09 12:57:00) [10]


> icWasya ©   (09.11.07 12:51) [12]
>
> а почему так
> FObservers.Add(@AObserver);
>
> а не так
> FObservers.Add(AObserver);
> ???


[Pascal Error] Unit2.pas(60): E2010 Incompatible types: 'Pointer' and 'IObserver'


pathfinder   (2007-11-09 12:57:00) [11]


> Anatoly Podgoretsky ©   (09.11.07 12:55) [13]


Большое спасибо! Это самый ценный совет.


Anatoly Podgoretsky   (2007-11-09 12:55:00) [12]


> Я же говорю, что это не реальная задача, а просто для примера.

Тренируйся на кошках.


icWasya   (2007-11-09 12:51:00) [13]

а почему так
FObservers.Add(@AObserver);

а не так
FObservers.Add(AObserver);
???


pathfinder   (2007-11-09 11:30:00) [14]

И потом вопрос ведь не в том, как оптимальней решить ЭТУ задачу, а что не так в реализации?


pathfinder   (2007-11-09 11:28:00) [15]


> Попробуй измерить время выполнения твоего алгоритма и предложенного
> товаришшем Ega23. Последний будет работать на порядок быстрее.
>  Не для того этот шаблон создавался, чтоб на нём такое вытворяли.
>


Я же говорю, что это не реальная задача, а просто для примера.


Dib@zol   (2007-11-09 11:27:00) [16]

Попробуй измерить время выполнения твоего алгоритма и предложенного товаришшем Ega23. Последний будет работать на порядок быстрее. Не для того этот шаблон создавался, чтоб на нём такое вытворяли.


pathfinder   (2007-11-09 11:25:00) [17]


> А нафика изобретать велосипед с треугольными колёсами? Поищи
> лучше в гугле задачи на применение этого шаблона, и не майся
> дурью. ЗЫ Мне аж плохо стало, когда я все эти навороты увидал.
> ..


Так какая разница какая задача? Вопрос-то в реализации..


Ega23   (2007-11-09 11:24:00) [18]


> Не стыдно, это же "батонокидательство"!


Это наиболее быстрый и дешёвый способ решения КОНКРЕТНОЙ проблемы.
Остальное - побоку.


Dib@zol   (2007-11-09 11:24:00) [19]

А нафика изобретать велосипед с треугольными колёсами? Поищи лучше в гугле задачи на применение этого шаблона, и не майся дурью. ЗЫ Мне аж плохо стало, когда я все эти навороты увидал...


ЮЮ   (2007-11-09 11:22:00) [20]

> [3] Ega23 ©   (09.11.07 11:19)


> Всё.


Не стыдно, это же "батонокидательство"!
А тут речь о Наблюдателе.
З.Ы. Не зря наблюдение за наблюдающим стоит дороже :)


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо