I’m sure this check is for a reason, namely, a component can remove several others in its destructor. I sometimes use this idiom (iteration backwards w/recheck agains count) exactly for this reason.
Indeed, there is a reason. It sholdn't be removed, but something has to be done.procedure
TApplication.DoIdleActions can be found in the same file and has the following lines:
i := Screen.CustomFormCount-1;
while i >=0 do begin { While loop to allow number of forms to change during loop }
CurForm:=Screen.CustomForms[i];
if CurForm.FormStyle=fsSplash then
CurForm.Hide;
i:=Min(i,Screen.CustomFormCount)-1;
end;
Also, in the same file is procedure
TApplication.IconChanged, procedure that has the following lines.
i := Screen.CustomFormCount-1;
while i >=0 do begin { While loop to allow number of forms to change during loop }
CurForm:=Screen.CustomForms[i];
CurForm.Perform(CM_ICONCHANGED, 0, 0);
i:=Min(i,Screen.CustomFormCount)-1;
end;
In addition to the lines
i:=Min(i,Screen.CustomFormCount)-1;, there is a useful comment writing that that the number of forms is allowed to change. It's easy to read and understand that code.
After reading three comments in that file that a while loop is used instead of a for loop because the number of whatever is allowed to change during loop you read the code below.
procedure TApplication.DoBeforeFinalization;
var
i: Integer;
begin
if Self=nil then exit;
for i := ComponentCount - 1 downto 0 do
begin
// DebugLn('TApplication.DoBeforeFinalization ',DbgSName(Components[i]));
if i < ComponentCount then
Components[i].Free;
end;
end;
Obviously you would consider something is wrong.
I think the code of the routines should look alike, be similar, but which code would the lcl developers prefer? The code of
TApplication.DoBeforeFinalization needs at least an additional comment.
The equivalent of
TApplication.DoIdleActions and
TApplication.IconChanged would be
procedure TApplication.DoBeforeFinalization;
var
i: Integer;
begin
if Self=nil then exit;
i:=ComponentCount-1;
while i>=0 do begin { While loop to allow number of components to change during loop }
// DebugLn('TApplication.DoBeforeFinalization ',DbgSName(Components[i]));
Components[i].Free;
i:=Min(i,ComponentCount)-1;
end;
end;