Class TFreeNotificationObserver
Unit
Declaration
type TFreeNotificationObserver = class(TComponent)
Description
Observe when something is freed, and call an event then. You need to set Observed of this component to make it notified about freeing of something. When the Observed is freed, this component will make OnFreeNotification event.
An example code using it:
type TChild = class(TComponent) end; TContainer = class(TComponent) private FChild: TChild; FChildObserver: TFreeNotificationObserver; procedure SetChild(const Value: TChild); procedure ChildFreeNotification(const Sender: TFreeNotificationObserver); public constructor Create(AOwner: TComponent); property Child: TChild read FChild write SetChild; end; implementation constructor TContainer.Create(AOwner: TComponent); begin inherited; FChildObserver := TFreeNotificationObserver.Create(Self); FChildObserver.OnFreeNotification := @ChildFreeNotification; end; procedure TContainer.SetChild(const Value: TChild); begin if FChild <> Value then begin FChild := Value; FChildObserver.Observed := Value; end; end; procedure TContainer.ChildFreeNotification(const Sender: TFreeNotificationObserver); begin FChild := nil; end;
Using this is an alternative to observing freeing using standard TComponent.FreeNotification / TComponent.RemoveFreeNotification mechanism https://castle-engine.io/modern_pascal#_free_notification . Using TFreeNotificationObserver
is:
A bit simpler and it's harder to make a mistake.
E.g. the line
FChildObserver.Observed := Value
is simpler than the typical equivalent lines required to unregister notification of the old value and register notification of the new value. (See https://castle-engine.io/modern_pascal#_free_notification example of FreeNotification usage.)The TContainer doesn't need to descend from TComponent.
You can manually free FChildObserver in the TContainer.Destroy.
Reliable if one class wants to observe freeing of multiple properties, and some of those properties may be sometimes equal. In this case using FreeNotification / RemoveFreeNotification with the main class would be unreliable (as RemoveFreeNotification removes the notification, even if you registered to it twice by FreeNotification), and requires complicated code to handles these special cases.
Using this component as a "proxy" to track each property is simpler, there's no additional code to handle this case. You just need different observer for each property to be observed.
As the owner of this TFreeNotificationObserver
instance (given as parameter to the constructor, TFreeNotificationObserver.Create) you almost always want to pass the instance that has the method you will associate with OnFreeNotification. In most cases (see also example above) this is available as just "Self". This means that TFreeNotificationObserver
will be freed (and will no longer generate OnFreeNotification) when the instance holding the associated method is freed, not later (which would mean the notification callback is called on non-existing instance, leading to an access violation).
Hierarchy
- TObject
- TPersistent
- TComponent
- TFreeNotificationObserver
Overview
Methods
procedure Notification(AComponent: TComponent; Operation: TOperation); override; |
|
destructor Destroy; override; |
Properties
property OnFreeNotification: TFreeNotificationEvent read FOnFreeNotification write FOnFreeNotification; |
|
property Observed: TComponent read FObserved write SetObserved; |
Description
Methods
procedure Notification(AComponent: TComponent; Operation: TOperation); override; |
|
This item has no description. |
destructor Destroy; override; |
|
This item has no description. |
Properties
property OnFreeNotification: TFreeNotificationEvent read FOnFreeNotification write FOnFreeNotification; |
|
Called when we receive notification that something was freed. |
property Observed: TComponent read FObserved write SetObserved; |
|
Setting this property makes the given component observed, freeing it will make OnFreeNotification. When setting, the previous value of this property stops being observed. Note that this property will be automatically changed to |
Generated by PasDoc 0.16.0-snapshot.