我做了这个声明:private...T:TTimer
现在当我在创建后释放 T
时,指针仍然肯定存在,但只要目标对象被销毁,对该指针的任何操作都可能导致 Invalida Pointer Operation
所以我只想知道目标对象是否被销毁。我怎样才能做到这一点?
(我不想使用 FreeAndNil
)
最佳答案
一点背景。
指针和对象是有区别的。
如果你有一个 TTimer 类型的变量(或字段),它是一个指针,可以指向 TTimer 类的对象。为了使用它,您需要创建对象。
下面是这种情况的一个小内存映射(一个创建的对象)。
|------|
| T | Contains address of object
|------|
| |
|
|
| |
|------|
|object|
| |
|------|
如果释放对象,则不会释放指针。它只是保留值,但对象不再存在(可能内存现在用于其他目的)。如果你试图访问它,你会得到一个错误,因为你正在访问一 block 不属于你的内存。 内存映射如下所示:
|------|
| T | Contains address of object
|------|
| |
|
|
| |
|------|
| | Memory previously known as your object.
| |
|------|
这就是为什么你必须将指针设置为 nil 的原因,即使它有再次使用的可能性很小。
请注意,当您将指针分配给另一个相同类型的变量时。两个指针都指向同一个对象。如果一个被释放(并希望被清除)另一个现在指向未使用的内存。这就是您必须小心复制指针的原因。
如果不想用free和nil,就得自己把指针设为nil。或者你应该使用一种使用垃圾收集的语言。或者你可以使用第三种方式(但它可能比 FreeAndNil 更麻烦):
介绍智能指针:
TSmartPointer<T: class> = record
private
FPointer: T;
procedure SetPointer(const Value: T);
public
class function Create(const APointer: T): TSmartPointer<T>; static;
procedure Free;
property Pointer: T read FPointer write SetPointer;
end;
class function TSmartPointer<T>.Create(const APointer: T): TSmartPointer<T>;
begin
Result.FPointer := APointer;
end;
procedure TSmartPointer<T>.Free;
begin
FPointer.Free;
FPointer := nil;
end;
procedure TSmartPointer<T>.SetPointer(const Value: T);
begin
if Value=nil then
Free
else
FPointer := Value;
end;
你可以这样使用:
var
smart : TSmartPointer<TButton>;
smart := TSmartPointer<TButton>.Create(TButton.Create(nil));
try
finally
smart.Free;
end;
或者:
smart := TSmartPointer<TButton>.Create(TButton.Create(nil));
try
finally
smart.Pointer := nil;
end;
清除对象和指针。但 FreeAndNil 仍然是最好的解决方案。
关于delphi - 如何判断组件是否被销毁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5401102/