关于Object被Destroy之后,该Object的原引用==null的问题

由于C#本身有GC机制,当对象的引用为0的时候就会被垃圾回收,对应的引用则会被置为null, 但Unity里边,调Destroy删除一个Object,只是释放了Unity的资源,而在C#层面,这个Object对应的引用都还在,那么它便不会被当成垃圾回收掉,所以C#层的资源并没有释放,但是拿它的引用跟null做对比确实相等的。代码跟到Unity Object脚本的实现,Unity里的MonoBehaver是继承自Object的,包括所有的Component也都是。跟到Object类之后 发现以下几句:

public static bool operator ==(Object x, Object y);
public static bool operator !=(Object x, Object y);

Object类重载了操作符 == 和 !=  ,所以Destroy了一个Unity对象的之后,在C#层的资源其实并没有被释放掉,当拿对应的引用变量来跟null做== !=判定的时候,因为对应的这个实例其实还是存在的,所以就会走到 被重载的==和!=操作符里,然后Unity直接给返回了一个true.      
     到这里应该基本上都清楚了,不过今天跟同事讨论的时候,发现用System.object去引用一个Unity的Object对象,然后Destroy调这个Object,再拿这个system.object的引用去跟null比较,返回的也是true的,当时还没想通呢,因为System.object是C#自己的类,并没有重载== 和!=操作符,以为应该返回false才对。现在想想,当时竟然把面向对象的概念都忘了。System.object在C#里是所有类的父类,而Unity.Object也是C#写的,自然System.object也是Unity.Object的父类,那么拿一个父类引用对象去指向一个子类实例,而子类实例重载了父类的方法,那么父类里的方法自然就被隐藏掉了,实际调起的就是子类重载后的方法了。所以在上面的这个System.object引用Unity.Object的情况里,Object被Destroy之后,由于C#层的实例并没有被释放,所以当用System.object引用跟null做==判定的时候实际上走的还是Unity.Object里重载的这个==,因为这里的Unity.Object实际上是System.oobject的子类。

     这里说一个C#里另一个用来判null的操作符,?? 这个操作符并没有被Unity.Object重载,用来判Destroy之后的对象就不会返回true啦。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值