수색…


통사론

  1. try-except : [[[E : ExceptionType do 문에서]] [else 문]을 제외한 [statements]를 시도하십시오. [명령문] 끝;

    try-finally : try [statements] finally [statements] end;

메모리 누출을 피하기위한 간단한 try..finally 예제

실행 중에 예외가 발생하는 경우 리소스 (예 : 메모리) 누수가 발생하지 않도록 try - finally 를 사용하십시오.

아래 절차는 파일에 문자열을 저장하고 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;

파일을 저장하는 동안 예외가 발생하는지 여부에 관계없이 SL 은 해제됩니다. 모든 예외는 호출자에게 전달됩니다.

새로운 객체의 예외적 인 반환

함수 객체를 반환 하면 (호출자가 전달한 객체를 사용 하는 것과는 대조적으로) 예외가 발생해도 객체가 누출되지 않도록주의하십시오.

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;

순진한 프로그래머는 모든 예외 유형을 포착하여 해당 함수에서 nil 을 반환하려고 시도 할 수 있지만, 예외를 처리하지 않고 모든 예외 유형을 포착하는 일반적인 권장되지 않은 관례에 불과합니다.

Try-finally 안에 try-finally 중첩

try - finally 블록은 try - except 블록 안에 중첩 될 수 있습니다.

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

UseResource 내에서 예외가 발생하면 실행은 ReleaseResource 점프 ReleaseResource . 예외가 EResourceUsageError 이면 실행은 예외 처리기로 이동하고 HandleResourceErrors 호출 HandleResourceErrors . 다른 유형의 예외는 예외 처리기를 건너 뛰고 호출 스택을 차단하는 except 는 다음 try 버블 링됩니다.

에서 예외 AcquireResource 또는 ReleaseResource 실행이 건너 뛰는, 예외 핸들러로 이동하게됩니다 finally 대응하는 하나 때문에, 블록 try 블록이 아직 입력되지 않았거나 때문에 finally 블록이 이미 입력되어 있습니다.

try-finally 내부에 중첩 된 try를 사용합니다.

try - except 블록은 try - finally 블록 안에 중첩 될 수 있습니다.

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

는 IF EResourceUsageError 발생 UseResource2 , 다음 실행은 예외 핸들러로 이동하고 호출 HandleResourceError . 예외는 처리 된 것으로 간주되므로 실행은 UseResource3ReleaseResource 계속됩니다.

UseResource2 에서 다른 유형의 예외가 발생하면 여기에 표시되는 예외 핸들러가 적용되지 않으므로 실행이 UseResource3 호출을 건너 UseResource3 ReleaseResource 가 호출되는 finally 블록 finally 직접 이동합니다. 그런 다음 예외가 호출 스택을 버블 링하기 때문에 실행은 다음 적용 가능한 예외 핸들러로 이동합니다.

위의 예제에서 다른 호출에서 예외가 발생하면 HandleResourceErrors 가 호출 되지 않습니다 . 이는 다른 예외 호출이 해당 예외 처리기에 해당하는 try 블록 내부에서 발생하지 않기 때문입니다.

두 개 이상의 객체를 사용하여 try-finally

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

try-finally 블록 밖에서 nil 하여 객체를 초기화하지 않으면 그 중 하나가 생성되지 않으면 객체는 초기화되지 않았으므로 nil이 아니므로 finally 블록에서 AV가 발생합니다. 예외가 발생합니다.

Free 메소드는 객체가 nil인지 검사하여 두 객체를 nil 초기화하면 생성되지 않은 객체를 해제 할 때 오류를 방지합니다.



Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow