Szukaj…


Składnia

  1. Try-wyjątkiem: spróbuj [instrukcje] oprócz [[[na E: ExceptionType do instrukcja]] [else instrukcja] | [wyciągi] koniec;

    Spróbuj na końcu: spróbuj [instrukcje] w końcu [instrukcje] koniec;

Prosty przykład ... na koniec, aby uniknąć wycieków pamięci

Użyj try - finally aby uniknąć wycieku zasobów (takich jak pamięć) na wypadek wystąpienia wyjątku podczas wykonywania.

Poniższa procedura zapisuje ciąg znaków w pliku i zapobiega wyciekaniu TStringList .

procedure SaveStringToFile(const aFilename: TFilename; const aString: string);
var
  SL: TStringList;
begin
  SL := TStringList.Create; // call outside the try 
  try
    SL.Text := aString;
    SL.SaveToFile(aFilename);
  finally
    SL.Free // will be called no matter what happens above
  end;
end;

Bez względu na to, czy podczas zapisywania pliku wystąpi wyjątek, SL zostanie zwolnione. Każdy wyjątek trafi do dzwoniącego.

Wyjątkowo bezpieczny zwrot nowego obiektu

Gdy funkcja zwraca obiekt (w przeciwieństwie do używania obiektu przekazanego przez program wywołujący), należy zachować ostrożność, wyjątek nie powoduje przecieku obiektu.

function MakeStrings: TStrings;
begin
  // Create a new object before entering the try-block.
  Result := TStringList.Create;
  try
    // Execute code that uses the new object and prepares it for the caller.
    Result.Add('One');
    MightThrow;
  except
    // If execution reaches this point, then an exception has occurred. We cannot
    // know how to handle all possible exceptions, so we merely clean up the resources
    // allocated by this function and then re-raise the exception so the caller can
    // choose what to do with it.
    Result.Free;
    raise;
  end;
  // If execution reaches this point, then no exception has occurred, so the
  // function will return Result normally.
end;

Naiwni programiści mogą próbować wychwycić wszystkie typy wyjątków i zwrócić nil z takiej funkcji, ale to tylko szczególny przypadek ogólnej zniechęconej praktyki łapania wszystkich typów wyjątków bez ich obsługi.

Try-wreszcie zagnieżdżone w try-wyjątkiem

Blok try - finally może być zagnieżdżony w try - except bloku.

try
  AcquireResources;
  try
    UseResource;
  finally
    ReleaseResource;
  end;
except
  on E: EResourceUsageError do begin
    HandleResourceErrors;
  end;
end;

Jeśli wyjątek wystąpi w UseResource , wykonanie przeskoczy do ReleaseResource . Jeśli wyjątek to EResourceUsageError , wówczas wykonanie przeskoczy do modułu obsługi wyjątków i HandleResourceErrors . Wyjątki dowolnego innego typu pomijają procedurę obsługi wyjątków powyżej i przechodzą do kolejnej try - except blokowania stosu wywołań.

Wyjątki w AcquireResource lub ReleaseResource spowoduje wykonanie przejść do obsługi wyjątków, omijając finally blok, albo dlatego, że odpowiada try blok nie został jeszcze wprowadzony albo dlatego, że finally blok został już wprowadzony.

Spróbuj, z wyjątkiem zagnieżdżonego w środku spróbuj na końcu

Blok try - except może być zagnieżdżony w bloku try - finally .

AcquireResource;
try
  UseResource1;
  try
    UseResource2;
  except
    on E: EResourceUsageError do begin
      HandleResourceErrors;
    end;
  end;
  UseResource3;
finally
  ReleaseResource;
end;

Jeśli EResourceUsageError wystąpi w UseResource2 , wówczas wykonanie przeskoczy do modułu obsługi wyjątków i HandleResourceError . Wyjątek zostanie uznany za obsłużony, więc wykonanie będzie kontynuowane w UseResource3 , a następnie ReleaseResource .

Jeśli wyjątek innego typu wystąpi w UseResource2 , pokaz obsługi wyjątków tutaj nie będzie miał zastosowania, więc wykonanie przeskoczy nad wywołaniem UseResource3 i przejdzie bezpośrednio do bloku finally , gdzie zostanie ReleaseResource . Następnie wykonanie przeskoczy do następnego odpowiedniego modułu obsługi wyjątków, gdy wyjątek pojawi się na stosie wywołań.

Jeśli wystąpi wyjątek w jakimkolwiek innym wywołaniu w powyższym przykładzie, HandleResourceErrors nie zostanie wywołany. Jest tak, ponieważ żadne inne wywołanie nie występuje w bloku try odpowiadającym temu programowi obsługi wyjątków.

Spróbuj na końcu z 2 lub więcej obiektami

Object1 := nil;
Object2 := nil;
try
  Object1 := TMyObject.Create;
  Object2 := TMyObject.Create;
finally
  Object1.Free;
  Object2.Free;
end;

Jeśli nie zainicjujesz obiektów nil poza blokiem try-finally , jeśli jeden z nich nie zostanie utworzony, AV pojawi się w bloku ostatecznie, ponieważ obiekt nie będzie zerowy (ponieważ nie został zainicjowany) i spowoduje wyjątek.

Metoda Free sprawdza, czy obiekt nie ma wartości zerowej, więc inicjowanie obu obiektów wartością nil pozwala uniknąć błędów podczas uwalniania ich, jeśli nie zostały utworzone.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow