【发布时间】:2015-03-16 09:55:35
【问题描述】:
在以下示例代码中,对AssertTestObj() 的调用会导致访问冲突。
Project InvokeTest2.exe 引发异常类 $C0000005 并带有消息 '0x00000000 处的访问冲突:读取地址 0x00000000'。
调试时我可以看到TSafeCall<T>.Invoke() 中的Assigned(NotifyProc) 测试没有按预期工作 - 因此Invoke() 尝试执行NotifyProc 这是nil,从而导致访问冲突。
任何想法为什么会失败以及如何解决它?
program InvokeTest2;
{$APPTYPE CONSOLE}
uses
System.SysUtils;
type
TSafeCall<T> = class
public
type
TNotifyProc = reference to procedure (Item: T);
class procedure Invoke(NotifyProc: TNotifyProc; Item: T); overload;
end;
TOnObj = procedure (Value: String) of object;
{ TSafeCall<T> }
class procedure TSafeCall<T>.Invoke(NotifyProc: TNotifyProc; Item: T);
begin
if Assigned(NotifyProc) then
NotifyProc(Item);
end;
procedure AssertTestObj(OnExceptionObj_: TOnObj; Value_: String);
begin
TSafeCall<String>.Invoke(OnExceptionObj_, Value_);
end;
begin
try
TSafeCall<String>.Invoke(nil, 'works as expected');
AssertTestObj(nil, 'this causes an access violation!');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
【问题讨论】:
标签: delphi delphi-xe3