Delphi为了与COM结合, 在PASCAL中加入了原来没有的接口元素, 变相的也扩展了对OO的支持.但也正因为只是为了与COM结合, Delphi中的接口实现实际上是不完整的. 因为没有垃圾收集功能, 在接口的实现中加入了COM的引用记数功能, 而这个功能的引入可以说是所有使用接口的麻烦的开始. 而看上去很优雅的很方便的自动进行引用记数加减的编译器代码又加重了这个麻烦, 让习惯于object打交道的Delphi使用者感觉到接口的使用是个大麻烦.
麻烦的开始:
第一步 引用记数: 引用记数是在COM中应用很广的技术, 它用很简单的方法实在了一个方便的垃圾收集机制. 这个在接口为王的COM世界中, 一切都很OK. 但与Delphi的结合就不那么美好了, 原因看第二步.
第二步 自动的进行引用记数加减: 因为引用记数要求使用者在引用这个接口时, 要对引用记数加1, 而在释放这个接口时对引用记数减1, 这是一个很麻烦与繁琐的事情, 一个不小心, 就可能忘记了这事, 那么引用记数所对应的机制就会无效, 于是我们家可爱的Borland就在Delphi的编译器中自动的加入了这件事. 当这个接口的变量被付值时, 对应接口的引用记数就会自动加1, 变量被定为nil或超出范围时又会自动的减1, 完全的不用各位去操心这事, 多么的方便啊. 可这是真的方便吗?
Delphi很大的好处在于它对低层进行了深厚而且漂亮的封装, 但在接口这个问题上, 很明显没有处理好. 这体现在
根源: 自动的引用记数只对接口的引用进行了处理, 而没有对对象的引用进行处理. 于是, 当你写了一个有接口的类, 并且让它从TInterfacedObject这个实现了引用记数为0时就自杀的基类上继承时, 你的麻烦就开始了. 因为你一旦建立了这个类的对象, 然后从中得到了它的接口, 自动的引用记数就开始起了作用, 你再也不能使用原来的对象了, 你只能使用对象的接口, 要不然你的接口变量定为nil或超出作用范围. 你的可爱的对象就消失了, 你原来的对象引用就无效了.
帮凶: 一切都源自根源, 由于接口与对象的不一致处理, 那些TObjectList啦, TStrings啦这些常用的集合都不能用了, 因为你在其中保存的对象, 可能已经在其它地方被自动的释放了. 于是你不得不使用TInterfaceList, 然后再用一些小技巧来进行比如TStringHash之类的集合的功能, 要不然就要自己写代码重新作一个接口的版本出来了.
以上是在Delphi中使用接口要注意的事项, 其实说来只有一点, 用了接口就要一直用, 不能再回到原来的对象那上了, 唉, 上了贼船下来就难了. 不过接口后面所体现的OO精神与设计模式, 还是很方便的, 很多地方都说过了, 这儿就不说了.
2006.11.08修改:
引用记数,这个看上去很美的东东,其实不能保证对象的释放,如果有两个对象进行了循环引用了的话,那么这两个类就会永生啦
麻烦的开始:
第一步 引用记数: 引用记数是在COM中应用很广的技术, 它用很简单的方法实在了一个方便的垃圾收集机制. 这个在接口为王的COM世界中, 一切都很OK. 但与Delphi的结合就不那么美好了, 原因看第二步.
第二步 自动的进行引用记数加减: 因为引用记数要求使用者在引用这个接口时, 要对引用记数加1, 而在释放这个接口时对引用记数减1, 这是一个很麻烦与繁琐的事情, 一个不小心, 就可能忘记了这事, 那么引用记数所对应的机制就会无效, 于是我们家可爱的Borland就在Delphi的编译器中自动的加入了这件事. 当这个接口的变量被付值时, 对应接口的引用记数就会自动加1, 变量被定为nil或超出范围时又会自动的减1, 完全的不用各位去操心这事, 多么的方便啊. 可这是真的方便吗?
Delphi很大的好处在于它对低层进行了深厚而且漂亮的封装, 但在接口这个问题上, 很明显没有处理好. 这体现在
根源: 自动的引用记数只对接口的引用进行了处理, 而没有对对象的引用进行处理. 于是, 当你写了一个有接口的类, 并且让它从TInterfacedObject这个实现了引用记数为0时就自杀的基类上继承时, 你的麻烦就开始了. 因为你一旦建立了这个类的对象, 然后从中得到了它的接口, 自动的引用记数就开始起了作用, 你再也不能使用原来的对象了, 你只能使用对象的接口, 要不然你的接口变量定为nil或超出作用范围. 你的可爱的对象就消失了, 你原来的对象引用就无效了.
帮凶: 一切都源自根源, 由于接口与对象的不一致处理, 那些TObjectList啦, TStrings啦这些常用的集合都不能用了, 因为你在其中保存的对象, 可能已经在其它地方被自动的释放了. 于是你不得不使用TInterfaceList, 然后再用一些小技巧来进行比如TStringHash之类的集合的功能, 要不然就要自己写代码重新作一个接口的版本出来了.
以上是在Delphi中使用接口要注意的事项, 其实说来只有一点, 用了接口就要一直用, 不能再回到原来的对象那上了, 唉, 上了贼船下来就难了. 不过接口后面所体现的OO精神与设计模式, 还是很方便的, 很多地方都说过了, 这儿就不说了.
2006.11.08修改:
引用记数,这个看上去很美的东东,其实不能保证对象的释放,如果有两个对象进行了循环引用了的话,那么这两个类就会永生啦
Delphi通过引入接口元素以支持COM,实现了自动引用计数,但这带来了对象生命周期管理的问题。当使用接口后,必须持续使用接口访问对象,否则会导致对象意外销毁。此外,集合类也无法直接使用对象。
2万+

被折叠的 条评论
为什么被折叠?



