当前位置:编程学习 > VB >>

vb怎样释放类模块创建的对象

--------------------编程问答-------------------- set obj = nothing这句话没有释放
//
你是如何知道没有释放的? --------------------编程问答-------------------- set obj = nothing减少对象的引用计数,只有当引用对象的最后一个变量置为nothing后才会真正释放,如:
dim o1 as class
dim o2 as class
set o1=new class
set o2=o1

set o1=nothing  '这里对象不会被释放,只是减少引用计数
set o2=nothing  '这里才会真正释放
--------------------编程问答-------------------- 那你肯定是对象之间存在循环引用了 --------------------编程问答-------------------- 《高级Visual Basic编程(Advanced Visual Basic)》
第六章 循环引用

整整一章的内容讲这个,比这里零零碎碎地讨论完整多了。
认真学习吧! --------------------编程问答-------------------- 高级Visual Basic编程 --------------------编程问答--------------------
引用 2 楼  的回复:
set obj = nothing减少对象的引用计数,只有当引用对象的最后一个变量置为nothing后才会真正释放,如:
dim o1 as class
dim o2 as class
set o1=new class
set o2=o1

set o1=nothing  '这里对象不会被释放,只是减少引用计数
set o2=nothing  '这里才会真正释放

dim o1 as class   ' 这个你认为在内存里会是什么样的一个东西?一个含带代码的内存结构体?
                  ' 这只不过是个4字节的内存地址指针,而且目前没有指向任何地址
dim o2 as class   ' 当然,这个也不例外,也只不过是个空指针

set o1=new class  ' 到了这里才开始动态分配内存,创建出类实例的结构体
set o2=o1         ' 这里只不过是让两个指针同时指向一个内存地址而已,说明的是同一个类实例
                  ' 难道你认为到这里就会易做图出两个类实例?一个是原来的,
                  ' 另一个是应为赋值而新 new 出来的新实例?
set o1=nothing    ' 如果 VB 不会应为赋值语句导致自动 new 新的实例对象,那么这里就已经完成
                  ' 了释放过程。当然,也可能没释放完,可能是因为那个类本身用了API来动态创建
                  ' 资源,然后没有在类释放事件中释放干净。但是这是属于类程序编写的问题,而不是
                  ' 类应用的问题。
set o2=nothing    ' 这个就完全是多余的了 --------------------编程问答--------------------
引用 6 楼  的回复:
引用 2 楼  的回复:

set obj = nothing减少对象的引用计数,只有当引用对象的最后一个变量置为nothing后才会真正释放,如:
dim o1 as class
dim o2 as class
set o1=new class
set o2=o1

set o1=nothing  '这里对象不会被释放,只是减少引用计数
set o2=nothing  '这里……


怎么说也在csdn看见你很多次了,怎么连这个都不知道呢,set obj =nothing并不是吧对象赋值为空,只是把指针赋值为空 --------------------编程问答-------------------- 具体有没有出现循环引用的情况我现在还没有弄清,但是出现对象注销不了的情况是确定的 --------------------编程问答--------------------
引用 7 楼  的回复:
怎么说也在csdn看见你很多次了,怎么连这个都不知道呢,set obj =nothing并不是吧对象赋值为空,只是把指针赋值为空

的确,这个问题是我疏忽了,我一直以为 VB 的Set Obj=Nothing 和 VC 里的 delete(obj); 是一样的效果了,但经过测试,的确不一样。不过有一点你说错了,set obj = nothing 并不只是把指针赋值为空,而是触发了某个过程来处理类实例内存里的数据。我通过观察内存得知,VB 当 new 一个类实例的时候,这个类实例内存中有一个引用对象基数,而这个基数初始值是1,如果在程序里用了类似 Set o2=o1 这种类赋值的用法,这个类实例的引用对象基数会加1,同时,这个 o2 的地址也会被记录到类实例的引用列表内存中。当然,如果还有更多的类似 Set o3=o1、Set o4=o1 这种用法也会让这个基数继续加1,且同样会记录引用对象地址到实例内存区,之后,如果要释放这个类实例,必须对每一个引用对象做一次set obj = nothing操作,因为只有这样才能对应上实例里记录的每一个引用对象列表项,只有地址对应了,VB才会对那个引用对象基数进行减1操作,直到那个基数值为1时,相应还在引用对象列表的对象再做 set obj = nothing 操作时,才会最后触发类里的Terminate 过程和 VB 内部的资源释放过程。而这一系列的操作,并不只是像你说的设置某个指针地址那么简单,而是通过 set obj = nothing 这种 VB 上的写法,被 VB 转译成了一个复杂的执行过程。 --------------------编程问答--------------------
引用 9 楼  的回复:
引用 7 楼 的回复:
怎么说也在csdn看见你很多次了,怎么连这个都不知道呢,set obj =nothing并不是吧对象赋值为空,只是把指针赋值为空

的确,这个问题是我疏忽了,我一直以为 VB 的Set Obj=Nothing 和 VC 里的 delete(obj); 是一样的效果了,但经过测试,的确不一样。不过有一点你说错了,set obj = nothing 并不只是把指针赋值为空……

不错!不过这一点Msdn中关于set obj =nothing已有说明 --------------------编程问答-------------------- VB的资源,会在超过作用域后自动释放的,这一点特别让我怀念,不像C#、VB.NET提供了狗易做图的垃圾自动回收机制(虽然可以通过GC提前不安全地回收)。 --------------------编程问答-------------------- VB中的对象是由VB来管理的,VB中的new和VC中的new在行为上是两码事,虽然表面上看起来一样,这也是VB中没有delete(obj)的原因,VB会自动去做这样的事,带来的好处就是VB程序员不用太那么关心内存泄漏等等的问题;
vb中的set obj =nothing更像是一种申请,请求VB释放对象,但释不释放是取决于VB的对象管理器,VB的对象管理器使用引用计数来决定对象的存留,当引用计数等于0时就释放,反之则一直会存在。
如果不能释放对象,那就只有两个原因,要么如前面所说循环引用,要么这个对象不是VB的对象管理器创建的(没用VB的new来创建) --------------------编程问答-------------------- 谢谢各位了,本人比较菜,还是有点时不时的不能释放cls的对象 --------------------编程问答-------------------- 如何知道某个对象的引用计数是多少呢?有时候希望计数等于1就释放,而不是到0的时候由VB自动释放
补充:VB ,  API
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,