捉虫记之三:1+1 ≠ 2
虫虫的世界真的很奇妙。这几天闲来无聊,就把我调试过的BUG写出来,一来和大家分享一些故事,提供一些解决思路。二来也是想总结一下虫虫的一些规律,看看能否系统地进行调试。
1+1 怎么会不等于2呢?
这次遇到的问题就是这样,我在跟踪界面上一个错误。这个错误是这样发生的,当一个子窗体关闭的时候,原先的一个Grid中的数据就报错了。很奇怪吧。
我采用了常规的调试方法,在报异常的地方设下断点,看看到底什么地方执行错了。可是已经入调试堆栈,就发现傻眼了,怎么明明是A结果的代码,变量查看器,却显示了另外一个结果。
我说,完了,编译器出问题了。于是重启IDE。还是不行,再重启电脑。也不行!
这怎么办呢?
我告诉大家一个好办法。就是找一个同事,给他讲一遍这个故事。然后你就容易有灵感了。
灵感不一定来源于你的同事,灵感往往是你已经钻进牛角尖了,出来就能看见灵感了。找你的同时,非常有助于你跳出来。
我跳出来后,得到的灵感就是:
调试器没有错,肯定是对象被释放了!不然不会有这么莫名其妙的事情发生。
方向对了,方法就简单了,只要跟踪子窗体弹出前后,对象的释放是否正确即可。也可以在怀疑对象的Destroy中设下断点,看看什么时候被释放了。
最后发现是下面这样一段代码的常用法的变种,导致了不该释放的对象被释放了。
with TSubForm.Create(nil) do
try
/// some code here
finally
Free; /// 注意这里的Free。因为是with下的,所以是针对SubForm的。
end;
但有时会一不小心,写出了下面的:
oSubForm := TSubForm.Create(nil);
try
/// some code hiere
finally
Free; /// 注意这里的Free。因为不在with下的,所以是针对方法的对象的,也就是Self(C#中是this)。
end;
好了,知道问题在哪里,解决BUG就简单多了。