TGadgetAnimations is a TObjectList that holds a list of TGadgetAnimation:
TGadgetAnimations = class(TObjectList<TGadgetAnimation>)
There are multiple instances of TGadetAnimations created here:
constructor TGadgetMetaInfo.Create;
var
i: Integer;
begin
inherited;
for i := 0 to ALIGNMENT_COUNT-1 do
begin
fVariableInfo[i].Animations := TGadgetAnimations.Create;
The TObjectList.OwnsObjects property defaults to True and is not set to False for any instance of TGadgetAnimations. This means that TGadgetAnimations will call Free on the instances of TGadgetAnimation that it holds (which are added by the call to Add).
The TObjectList.Clear method will remove all instances of TGadgetAnimation that were added to that instance of TGadgetAnimations. Since OwnsObjects is True, calling Clear will also call Free on each instance.
When AddPrimary is called the first time for the instance, it assigns a reference to TGadgetAnimation to fPrimaryAnimation.
procedure TGadgetAnimations.Clone(aSrc: TGadgetAnimations);
var
i: Integer;
NewAnim: TGadgetAnimation;
begin
Clear;
NewAnim := TGadgetAnimation.Create(aSrc.PrimaryAnimation.fMainObjectWidth, aSrc.PrimaryAnimation.fMainObjectHeight);
NewAnim.Clone(aSrc.PrimaryAnimation);
AddPrimary(NewAnim); <-- This will assign fPrimaryAnimation if it is not assigned.
When Clone is called, it calls Clear, which frees the TGadgetAnimation instances that were previously created. But, it does not clear the fPrimaryAnimation reference, which is now pointing to unallocated memory.
Use the solution posted by Anders of overriding the Notify method.