1. 程式人生 > >C#-----------------------------回收機制中Destroy與null的作用

C#-----------------------------回收機制中Destroy與null的作用

icon des www ocl 技術 比較 view 情況 它的

關於Object被Destroy之後,該Object的原引用==null的問題

標簽: unityc#繼承對象 技術分享 分類: 由於C#本身有GC機制,當對象的引用為0的時候就會被垃圾回收,對應的引用則會被置為null, 但Unity裏邊,調Destroy刪除一個Object,只是釋放了Unity的資源,而在C#層面,這個Object對應的引用都還在,那麽它便不會被當成垃圾回收掉,所以C#層的資源並沒有釋放,但是拿它的引用跟null做對比確實相等的。代碼跟到Unity Object腳本的實現,Unity裏的MonoBehaver是繼承自Object的,包括所有的Component也都是。跟到Object類之後 發現以下幾句: [csharp]
view plain copy print?
  1. public static bool operator ==(Object x, Object y);
  2. 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啦。

C#-----------------------------回收機制中Destroy與null的作用