Примечание. Это будет работать только в том случае, если ваш потребитель также является производным от TComponent.
Чтобы избежать мертвых ссылок, вы можете запросить IInterfaceComponentReference
(доступно для каждого TComponent) из вашей формы, позвоните GetComponent
на этом интерфейсе и присоединитесь к FreeNotification
возвращенного компонента / формы.
Что происходит сейчас: когда форма уничтожается, она уведомляет всех «составителей списков» о том, что она собирается уничтожить себя, вызывая метод Notification
для потребителя с самим собой (формой) как AComponent
и opRemove
как операция. Таким образом, вы можете обнулить ссылку на интерфейс.
Но учтите, что ссылки на объекты и ссылки на интерфейсы не должны быть одинаковыми.
Также обязательно звоните RemoveFreeNotification
, когда вам больше не нужны уведомления, чтобы избежать ненужных звонков.
TSomeConsumer = class(TComponent)
private
FInterfaceToAService: ISomeInterface;
protected
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
public
procedure SetService(const Value: ISomeInterface);
end;
procedure TSomeConsumer.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited;
if (Operation = opRemove) and (AComponent = TObject(FInterfaceToAService)) then
SetService(nil); // Takes care of niling the interface as well.
end;
procedure TSomeConsumer.SetService(const Value: ISomeInterface);
var
comRef: IInterfaceComponentReference;
begin
if Supports(FInterfaceToAService, IInterfaceComponentReference, comRef) then
comRef.GetComponent.RemoveFreeNotification(self);
FInterfaceToAService := Value;
if Supports(FInterfaceToAService, IInterfaceComponentReference, comRef) then
comRef.GetComponent.FreeNotification(self);
end;