Sök…


Syntax

  1. Försök med undantag: försök [uttalanden] förutom [[[på E: ExceptionType do statement]] [else statement] | [uttalanden] slut;

    Försök äntligen: försök [uttalanden] slutligen [uttalanden] slut;

Enkelt försök .. slutligt exempel för att undvika minnesläckor

Använd try - finally att undvika läckande resurser (t.ex. minne) om ett undantag inträffar under körning.

Proceduren nedan sparar en sträng i en fil och förhindrar att TStringList läcker.

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;

Oavsett om ett undantag inträffar vid lagring av filen kommer SL att frigöras. Alla undantag går till den som ringer.

Undantagssäker återkomst av ett nytt objekt

När en funktion returnerar ett objekt (i motsats till att använda ett som har skickats in av den som ringer), var noga med att ett undantag inte får objektet att läcka.

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;

Naiva programmerare kan försöka fånga alla undantagstyper och återlämna nil från en sådan funktion, men det är bara ett speciellt fall av den allmänna avskräckta praxisen att fånga alla undantagstyper utan att hantera dem.

Försök att äntligen kapsla in i try-utom

Ett try - finally block kan kapslas in i ett try - except block.

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

Om ett undantag inträffar i UseResource kommer ReleaseResource att ReleaseResource till ReleaseResource . Om undantaget är en EResourceUsageError , kommer exekveringen att hoppa till undantagshanteraren och anropa HandleResourceErrors . Undantag av någon annan typ kommer att hoppa över undantagshanteraren ovan och bubbla upp till nästa try - except blockera samtalstaket.

Undantag i AcquireResource eller ReleaseResource orsakar exekveringen att gå till undantag handler, hoppa över finally blocket, antingen på grund av motsvarande try blocket inte har angetts ännu eller på grund av finally blocket har redan matats in.

Försök-utom kapslade in try-slutligen

Ett try - except block kan kapslas in i ett try - finally blockera.

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

Om en EResourceUsageError inträffar i UseResource2 , kommer exekveringen att hoppa till undantagshanteraren och ringa HandleResourceError . Undantaget kommer att betraktas som hanterat, så körning fortsätter till UseResource3 och sedan ReleaseResource .

Om ett undantag av någon annan typ förekommer i UseResource2 , då undantag handler show här inte kommer att gälla, så utförandet kommer att hoppa över UseResource3 samtalet och gå direkt till finally blocket, där ReleaseResource kommer att kallas. Därefter hoppas exekveringen till nästa tillämpliga undantagshanterare när undantaget bubblar upp samlingsstacken.

Om ett undantag inträffar i något annat samtal i exemplet HandleResourceErrors kommer HandleResourceErrors inte att HandleResourceErrors . Detta beror på att inget av de andra samtalen inträffar i try som motsvarar den undantagshanteraren.

Försök slutligen med två eller flera objekt

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

Om du inte initialiserar objekten med nil utanför try-finally blocket, om ett av dem inte skapas, kommer en AV att inträffa på det slutliga blocket, eftersom objektet inte kommer att vara noll (eftersom det inte initialiserades) och kommer att orsaka ett undantag.

Metoden Free kontrollerar om objektet är noll, så att initiera båda objekten med nil undviker fel när de frigörs om de inte skapades.



Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow