由于C#自己有GC机制,当东西的引用为0的时候就会被垃圾回收,对应的引用则会被置为null, 但Unity里边,调Destroy删除一个Object,只是释放了Unity的资源,而在C#层面,这个Object对应的引用都还在,那么它便不会被当成垃圾回收失,所以C#层的资源并没有释放,但是拿它的引用跟null做比拟确实相等的。代码跟到Unity Object脚本的实现,Unity里的MonoBehaver是担任自Object的,包孕所有的Component也都是。跟到Object类之后 发明以下几句:
[csharp]
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啦。