经常看到有人在分配了一个资源(如创建对象、申请内存、打开句柄等)后,不习惯用try...finally来确保资源得以释放,比如这篇转贴的贴子 ,有如下一段代码(原来的注释被我去掉了):
001 var
002 reg:TRegistry;
003 s:String;
004 begin
005 reg:=TRegistry.Create;
006 reg.RootKey:=HKEY_CURRENT_USER;
007 if reg.OpenKey('/Software/Delphi使用技巧',true) then
008 begin
009 s:=reg.ReadString('文章名称');
010 reg.CloseKey;
011 end;
012 reg.Free;
013 ...
014 end;
上面这段代码其实有很严重的问题:第009行,如果不存在以“文章名称”为名字的值,则ReadString会返回空串,但如果这个值存在但类型不是字串型,则ReadString会抛出一个异常,后果是reg这个TRegistry的实例得不到释放,其实要避免这一点很容易,把try...finally这个好东东加上即可:
001 var
002 reg:TRegistry;
003 s:String;
004 begin
005 reg:=TRegistry.Create;
006 try
007 reg.RootKey:=HKEY_CURRENT_USER; //这句可以没有,对象创建时默认就是这个根键
008 if reg.OpenKey('/Software/Delphi使用技巧',true) then
009 begin
010 s:=reg.ReadString('文章名称');
011 reg.CloseKey; //这句也可以省略,析构或再调用OpenKey时会自动调用CloseKey
012 end;
013 finally
014 reg.Free;
015 end;
016 ...
017 end;
这样就能保证无论如何,reg都会被析构,常见的还有:
with TDialogAbout.Create(nil) do
try
ShowModal;
finally
Free;
end;
GetMem(buf, 1024);
try
...
finally
FreeMem(buf);
end;
hFile := CreateFile(....);
if INVALID_HANDLE_VALUE<>hFile then
try
...
finally
CloseHandle(hFile);
end;
if NOERROR=FindFirst('*.*', faAnyFile, searchRec) then
try
repeat
...
until NOERROR<>FindNext(searchRec);
finally
FindClose(searchRec);
end;
...
finally的效率很高(不象except),几乎不多耗系统资源(特别是流程自然,中途没有exit之类时),为什么不多用,让自己的程序更健壮呢?