Embarcadero Delphi
try, except 및 finally 사용
수색…
통사론
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
. 예외는 처리 된 것으로 간주되므로 실행은 UseResource3
및 ReleaseResource
계속됩니다.
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
초기화하면 생성되지 않은 객체를 해제 할 때 오류를 방지합니다.