2015-09-07 2 views
0

У меня есть класс, который создает несколько объектов игры единиц в иерархии сцены. Этот класс реализует IDisposable. Должен ли я обрабатывать эти игровые объекты, поскольку они были управляемыми или неуправляемыми ресурсами?Доступны ли управляемые или неуправляемые ресурсы игровых объектов Unity?

Я следую за Dispose pattern, поэтому, где я должен поставить вызовы, подобные GameObject.Destroy (myGameObject)?

Спасибо

Edit: Ok, позволяет сказать, что я хочу, чтобы уничтожить игровые объекты, экземпляры этого класса, когда он выходит из области видимости. Как вы тогда начнете?

Редактировать 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 для вас, чтобы написать «Convient» код, как:

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

Но в Unity это не имеет никакого смысла. Я не могу представить себе случай, когда в обновлении GameObjects создаются, а затем уничтожаются.

+0

Ну, на самом деле класс не является контейнером. Он просто ссылается на игровые объекты в сцене. Они продолжают существовать даже после того, как экземпляр класса перестает быть. См. Мое редактирование. – rluks

+0

Я просто использовал «контейнер» из-за отсутствия контекста. Для уничтожения в Unity используйте GameObject.Destroy. Даже после этого память может быть по-прежнему занята игровым объектом, если GC не собирает ее. Любой IDisposable не поможет вам полностью удалить объект. Цель состоит в том, чтобы освободить неуправляемые ресурсы. GameObject не является неуправляемым ресурсом, поэтому для него не требуется IDisposable. Продолжить существование означает видимое на сцене? –

+0

Да, эти игровые объекты остаются в сцене в иерархии. – rluks

1

Да, я думаю, вы слегка неправильно поняли, что используется IDisposable и using. Вы не должны использовать IDisposable везде, чтобы избавиться от объекта - это роль сборщика мусора, он лучше знает, когда объект будет удален.

IDisposable и using заявление используются в качестве try/finally заявления (конечно, это гораздо сложнее, под капотом) и убедитесь, что объект будет удален/решен сразу после его больше не используется. Это не всегда проблема с управляемыми/неуправляемыми ресурсами.

Использование инструкции using не гарантирует, что ваш игровой объект будет удален. Все зависит от того, есть ли другие объекты, указывающие на него. Поскольку он выглядит как корневой объект, я считаю, что он будет проводиться как можно дольше GC. Обратите внимание, что даже если GC вызывает Dispose() на вашем объекте, пока он ссылается, он будет оставаться в специальной очереди до тех пор, пока он не будет отпущен.

С другой стороны, если ваш GameObject является менее Game, больше Object, вы не должны рассматривать его с помощью утилизации IDisposable, пока он не какой-то образом связан с некоторым подключением/файлом/внешним ресурсом. GC будет требовать память, как только ваш объект считается мусором. Просто учтите, что IDisposable - это то, что CLR относится немного к другому, и это не всегда путь.

EDIT

По вашему вопросу от редактирования - в основном, когда объекты выходит из области видимости, вы ничего не делать - если GC считает это мусор, он будет удален с ближайшей коллекцией GC, которые происходят. Вот почему C# считается управляемым языком и почему вы не выпускаете память самостоятельно.

+0

Я понимаю, что вы говорите о сборщике мусора, см. Мое редактирование. – rluks

+0

@ Pan.student См. Мое редактирование. – Kamo

+0

Ну, игровые объекты, созданные классом, все еще существуют в сцене даже после того, как экземпляр класса выходит за рамки. Я могу написать метод с именем что-то вроде Cleanup или MyDispose, который Destroys gameobjects и вызывать его вручную, после того как я не буду работать с экземпляром класса. Но для Destroys было бы удобно обрабатывать Dispose. – rluks