対応したこと
- インスタンスが破棄される時に
メンバ変数に定義しているすべてのデリゲートに null を代入するようにした
MonoBehaviour を継承しているクラスの場合
- OnDestroy 関数ですべてのデリゲートにnullを代入する
対応前
public class Example : MonoBehaviour
{
public Action mCompleted;
public Func<bool> mCanPlay ;
}
対応後
public class Example : MonoBehaviour
{
public Action mCompleted;
public Func<bool> mCanPlay ;
private void OnDestroy()
{
mCompleted = null;
mCanPlay = null;
}
}
MonoBehaviour を継承していないクラスの場合
- IDisposable インターフェースを実装する
- Dispose 関数を定義してすべてのデリゲートにnullを代入する
- Dispose 関数を MonoBehaviour を継承しているクラスの OnDestroy で呼び出す
対応前
public class Hoge
{
public Action mCompleted;
public Func<bool> mCanPlay ;
}
public class Example : MonoBehaviour
{
private Hoge m_hoge = new Hoge();
}
対応後
public class Hoge : IDisposable
{
public Action mCompleted;
public Func<bool> mCanPlay ;
public void Dispose()
{
mCompleted = null;
mCanPlay = null;
}
}
public class Example : MonoBehaviour
{
private Hoge m_hoge = new Hoge();
private void OnDestroy()
{
m_hoge.Dispose();
}
}
- IDisposable は実装する必要はないが、わかりやすくするために実装した
メモ
- プロファイラを見ていても、何がリークしているのかがわからなかった
- Cygames さんのスライドで、デリゲートには null を代入すると良いと知っていたので、開発中もデリゲートに null を代入するようにしていたが、いくつか null を代入していないデリゲートが存在した
- ソースコードを見直して、null を代入していないデリゲートにも null を代入するようにしたところ、強制終了の不具合が直った
参考資料
speakerdeck.com
関連記事