2015-09-07 189 views
0

我有一個實例化場景層次結構中的幾個統一遊戲對象的類。這個類實現了IDisposable。我應該如何管理這些遊戲對象,因爲它們是託管資源還是非託管資源?Unity遊戲對象是託管還是非託管資源?

我正在關注Dispose pattern,所以我應該在哪裏放置類似GameObject.Destroy(myGameObject)的調用?

謝謝

編輯: 好吧,讓說,我想,當它超出範圍摧毀這個類實例化的遊戲對象。你將如何繼續?

編輯2: 我正在測試處置。我發現解決方案。它不會自動工作,因爲GameObject.Destroy(myGameObject)不能從不同的線程調用。它會拋出一個錯誤CompareBaseObjectsInternal。所以,當不再需要時,我打電話myClass.Dispose()。此外,我是否將Unity GameObject作爲託管或非託管來處理似乎並不重要。

myMain() 
{ 
    DisposeTestClass test = new DisposeTestClass(); 
    //... 
    test.Dispose(); 
} 


class DisposeTestClass : System.IDisposable 
{ 

    public GameObject uselessGameobject { get; private set; } 

    public DisposeTestClass() 
    {   
     uselessGameobject = new GameObject("Useless gameobject"); 
    } 

    #region IDisposable 
    private bool _disposed; 

    ~DisposeTestClass() 
    { 
     Debug.Log("~DisposeTestClass()"); 

     this.Dispose(false); 
    } 

    public void Dispose() 
    { 
     Debug.Log("Dispose()"); 

     this.Dispose(true); 
     System.GC.SuppressFinalize(this); 

    } 

    protected virtual void Dispose(bool disposing) 
    { 
     Debug.Log("Dispose(bool)"); 

     if(_disposed) 
     { 
      Debug.Log("Disposed. Return."); 
      return; 
     }   

     if(disposing) 
     { 
      Debug.Log("Disposing of managed resources..."); 

      // clean up managed resources 
      /* 
      if(uselessGameobject != null) 
      { 
       GameObject.Destroy(uselessGameobject); 
       Debug.Log("Game object destroyed."); 
      } 
      else 
      { 
       Debug.Log("Game object is null."); 
      }*/ 

     } 

     Debug.Log("Cleaning up unmanaged resources..."); 
     // clean up unmanaged resources 

     if(uselessGameobject != null) 
     { 
      GameObject.Destroy(uselessGameobject); 
      Debug.Log("Game object destroyed."); 
     } 
     else 
     { 
      Debug.Log("Game object is null."); 
     } 

     // set the flag 
     Debug.Log("Setting the disposed flag."); 
     this._disposed = true; 
    } 
    #endregion 

} 

}

回答

2

不,你不應該實現IDisposable。但是你可以 :)。

「所以我應該把調用GameObject.Destroy(myGameObject)」,當你想要你的對象被銷燬?實際上,無論您調用myContainer.Dispose()還是GameObject.Destroy(gObj)都無關緊要。

來實現IDisposable你的唯一原因是爲了寫「無限便捷」這樣的代碼:

using(var container = new MyContainer()) 
using(var somethingElse = new MyObject()) 
{ 
    \\Logic for container and somethingElse 
} 

但在團結這個是沒有意義的。我很難想象在Update GameObjects被創建並銷燬時的情況。

+0

那實際上這個類不是一個容器。它只是引用場景中的遊戲對象。甚至在班級不再這樣的情況下,他們仍然存在。看我的編輯。 – rluks

+0

我剛剛使用「容器」,因爲缺乏上下文。在Unity中銷燬使用GameObject.Destroy。即使在那之後,除非GC收集它,內存可能仍然會被gameobject佔用。無論是IDisposable都不會幫助您完全刪除對象。它的目的是釋放非託管資源。 GameObject不是非託管資源,因此它不需要IDisposable。 繼續存在意味着在現場可見? –

+0

是的,這些gameobjects留在層次結構的場景中。 – rluks

1

呵呵,我想你有點誤解了IDisposableusing聲明是用來做什麼用的。你不應該在任何地方實現IDisposable來擺脫一個對象 - 這是垃圾收集器的角色,它更清楚何時丟棄對象。

IDisposableusing語句被用作try/finally語句(當然它更加複雜),並確保在不再使用該對象之後立即刪除/解析該對象。它並不總是一個託管/非託管資源問題。

使用using聲明不會確保您的遊戲對象將被丟棄。這一切都取決於是否有其他物體指向它。由於它看起來像一個根對象,我相信它會盡可能地由GC保持。請注意,即使GC在對象上調用了Dispose(),只要它被引用,它就會保留在特殊隊列中,直到它被釋放。

在另一方面,如果你GameObject是少Game,更多的Object,你不應該考慮使用IDisposable只要它不以某種方式與一些連接/文件/外部資源連接配置它。只要你的對象被認爲是垃圾,GC就會聲稱記憶。只要考慮到,IDisposable是CLR對待有點不同,並不總是要走的路。

編輯

據編輯你的問題 - 基本上當一個對象超出範圍時,你什麼都不做 - 如果GC認爲垃圾,它會與發生的最接近的GC集合中刪除。這就是C#被認爲是託管語言的原因,以及爲什麼你不能自行釋放內存。

+0

我明白你對垃圾收集器有何看法,請參閱我的編輯。 – rluks

+0

@ Pan.student看我的編輯。 – Kamo

+0

那麼,即使在類的實例超出範圍之後,該類創建的gameobjects仍然存在於場景中。我可以編寫名爲類似於Cleanup或MyDispose的方法,它可以銷燬gameobjects並在我不打算使用該類的實例後手動調用它。但是Distroys在Dispose中處理會很方便。 – rluks