var
aClass: TTestClass;
begin
try
aClass:= TTestClass.Create;
// Do something
finally
if aClass <> nil then aClass.Free;
end;
end;
这将提高 W1036 的值,但有一项检查可以使其尽可能内存安全。我怎样才能让编译器看到它的安全性,这样它就不会在整个项目中发出数百个警告?这使得警告列表基本上毫无用处,因为有用的警告列表被埋在数百个这样的警告列表中。
做
aClass := nil;
,奇怪的是编译器很满意。我猜它唯一做的就是在其范围内寻找直接分配?
谢谢!
在对
TTestClass.Create
进行赋值之前,aClass
可以引发异常,然后执行finally
子句,而aClass
仍未初始化。所以这个警告实际上是真的。
在开头添加
aClass := nil
可确保到达在 finally 子句中使用 aClass 的行时始终初始化 aClass。
然而,更典型的模式是将作业
aClass := TTestClass.Create
行放在 try
之前。这是有道理的,因为只有在分配了 try-finally
后,aClass
才有意义。
当有两个或多个变量需要保护时,首先分配
aClass := nil
的替代方案更为常见。然后首先分配 nil
可能会比嵌套的 try-finally 构造提供更好看的代码(但这已经更多是一个品味问题)。
所以这两种资源保护模式都很好:
模式1
A := TSomeClass.Create;
try
B := TSomeClass.Create;
try
// ... Do something ...
finally
B.Free;
end;
finally
A.Free;
end;
模式2
A := nil;
B := nil;
try
A := TSomeClass.Create;
B := TSomeClass.Create;
// ... Do something ...
finally
A.Free;
B.Free;
end;