I have written this piece of code:
FD := TList<double>.Create;
FN := TList<double>.Create;
RemList := TList<double>.Create;
dati := TStringList.Create;
try
try
//code
except
on E : Exception do
ShowMessage('Incorrect values. Error: ' + E.Message);
end;
finally
if Assigned(dati) then
dati.Free;
if Assigned(FD) then
FD.Free;
if Assigned(FN) then
FN.Free;
if Assigned(RemList) then
RemList.Free;
end;
I am using firemonkey so I won't have problems when I'll run this on mobile devices because ARC will manage the lifetime. But is this code safe when I am on windows?
I have read that I cannot have a finally and a catch all together so I need to have a nested try block. I guess that the best way is this:
FD := TList<double>.Create;
try
FN := TList<double>.Create;
try
RemList := TList<double>.Create;
try
//and so on...
finally
Rem.Free;
end;
finally
FN.Free;
end;
finally
FD.Free;
end;
Here I am sure that I'll free the object in any case and in a safe way but the code is hard to read. I have seen that Marco Cantu is suggesting the 2nd approach in object pascal handbook and I understand it, but in my case I want to avoid it.
Can something wrong happen in the first block of code I have written?
If I was you I'd use the second block of code because as you already know it's better; the TList<double>.Create (like the other constructors) are "safe" as you say but it's better if you always assume that there is a risk behind the corner.
Note that when I say safe I mean that they won't raise an exception if you call them in that way. An exception could happen in any case that you maybe cannot predict, so you really should protect the code with a try finally.
You are also using the Assigned() which is useless. If you look at the implemetation of Free you will find this code (it's also commented):
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
if Self <> nil then
Destroy;
{$ENDIF}
end;
The Assigned() returns true or false if the object is equal to nil or not, so basically you're doing an useless double check.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With