Что будет если по адресу уже другая процедура?

Модератор: Модераторы

Что будет если по адресу уже другая процедура?

Сообщение Sharfik » 05.01.2014 23:40:10

Встал вопрос, что будет если идет такая ситуация. Этап первый - создаются классы и у всех в один список собираем адреса процедур оповещения их о каком то изменении.
Этап второй - Всем элементам списка рассылается сообщение о изменении.
Вопрос в следующем, если кто то из них уже уничтожен, что будет с ним, при попытке его вызова? Свою программу я через проверну защитить смогу, но не нарушит ли это что то другое что будет находится где раньше была процедура?
Код: Выделить всё
TMyClass=class
public
procedure ChangeEvent(Sender:TObject);
end;


Код: Выделить всё
***
var
ListEvent:TList;
****
var
Item:TMyClass;
begin

Item:=TMyClass.create;
ListEvent.add(addr(item.ChangeEvent));
item.free;
end;



Код: Выделить всё
for i:=0 to ListEvent.Count-1 do
begin
try
EventProcedure:=Items[i];
EventProcedure(self); //go
except
//что будет с новыми данными в случае возникновения этой ситуации
end;
end;
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 791
Зарегистрирован: 20.07.2013 01:04:30

Re: Что будет если по адресу уже другая процедура?

Сообщение bormant » 07.01.2014 00:26:43

Открою маленький секрет: все экземпляры TMyClass будут иметь один и тот же адрес ChangeEvent при показанных выше объявлениях, если правильно путаю. Экземпляры класса отличаются данными, но имеют общий код. С каким классом работает код, определяет неявный параметр Self. Вот только тот Self -- это данные того экземпляра TMyClass, а не self непонятно какого вызывающего класса на момент вызова.
Аватара пользователя
bormant
постоялец
 
Сообщения: 407
Зарегистрирован: 21.03.2012 11:26:01

Re: Что будет если по адресу уже другая процедура?

Сообщение Sharfik » 07.01.2014 21:08:16

bormant писал(а):Открою маленький секрет: все экземпляры TMyClass будут иметь один и тот же адрес ChangeEvent при показанных выше объявлениях, если правильно путаю. Экземпляры класса отличаются данными, но имеют общий код. С каким классом работает код, определяет неявный параметр Self. Вот только тот Self -- это данные того экземпляра TMyClass, а не self непонятно какого вызывающего класса на момент вызова.

Согласен, неправильно пример привел. Насколько помню только объявления protected имеют разные копии.
Код: Выделить всё
TMyClass=class
private
FOnChangeEvent:TNotifyEvent; // В зависимости от экземпляра класса, будет свой обработчик. К примеру у каждой формы свой класс и обработчик.
public
property OnChangeEvent:TNotifyEvent .....
end;


Код: Выделить всё
***
var
ListEvent:TList;
****
var
Item:TMyClass;
begin

Item:=TMyClass.create;
....
ListEvent.add(addr(item.OnChangeEvent));
item.free;
end;



Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var
   i:integer;
   P:Pointer;
   EventProcedure:TNotifyEvent;
   M: TMethod;
begin
  for i := 0 to ListEvent.Count - 1 do
  begin
    P:=(ListEvent.Items[i]);
    M.Code := P;
    M.Data := nil; //self объекта-обработчика равен nil
    EventProcedure:=TNotifyEvent(M);
    try
       if Assigned(EventProcedure)then
        EventProcedure(Self); // В качестве Self передаем виновника возникновения событий
    except
        // Не происходит
    end;
  end;
end;

Проверил наконец, с доделками. Недостаток - без {$mode delphi} не работает. Except как раз и не вылетает из-за того, что сама функция не создается заново, а используется классами в едином виде как написана и кто к ней обращается. Второй параметр сохранять надо.
Спасибо в общем, докопался с подсказками до того, что там происходит. :D
Аватара пользователя
Sharfik
энтузиаст
 
Сообщения: 791
Зарегистрирован: 20.07.2013 01:04:30


Вернуться в Общие вопросы

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1

Рейтинг@Mail.ru