あなたの質問は少し奇妙な言葉でした。しかし、私が理解しているように、Luaスクリプトには、外部コードで割り当てられたオブジェクトへの参照があります。そして、Luaがこれらの参照を持っている限り、外部コードはそれらのリソースを解放しません。そして、あなたはそれらの資源が解放されるべきであると信じています。
最初に確認する必要があるのは、Luaインターフェースコードがメタメソッドを使用して参照を適切にクリーンアップすることです。つまり、Luaがオブジェクト参照で終了すると、Luaがオブジェクトで終了した__gc
ことを外部コードに通知するメタメソッドがアタッチされます()。
この投稿の残りの部分では、このコードが存在し、正しく機能していると想定します。これを自分で確認する必要があります。
その仮定を考えると、あなたが見ていることは、次の2つの理由のいずれかで起こります。
Luaコードはすべての参照の使用を終了しましたが、まだクリーンアップされていません。これは、Luaスクリプトがローカル変数、グローバル変数などの参照を持たなくなったことを意味します。この場合、Luaのガベージコレクターはまだ実行されておらず、クリーンアップされていません。したがって、でそれを行う必要がありますlua_gc(L, LUA_GCCOLLECT, 0);
。この場合、この関数を実行した後、Luaからのすべての参照がクリーンアップされているはずです。
Luaコードには、まだ潜んでいる外部オブジェクトへのアクティブな参照があります。
ケース#2に対処することは困難です。責任を負うのはLuaコードの責任です。何かを参照する必要があるときに参照を保存し、後でそれらの参照を忘れる必要があります。つまり、値を非ローカル変数に格納しないことを意味します(また、「非ローカル」とは、ネストされた関数定義で使用されるローカルを回避することも意味します)。
それらの参照がまだ存在する場所を見つける手段はありません。結局のところ、Luaの値には必ずしも名前が付いているわけではありません。また、Luaは、で可能なすべての変数を反復処理する方法を実際には提供していませんlua_State
。あったとしても、それらの参照を単に空白にする手段は確かにありません。結局のところ、Luaコードはまだそれらに触れることができます。それらをブランクにすると、Luaコードがそれらのオブジェクトと通信しようとしたときにクラッシュします。ですから、あなたがやりたいことができたとしても、それは逆効果になります。
これに対処するための3つの方法のいずれかをお勧めします。
スクリプティングで規律を行使します。Lua以外のすべてのオブジェクトがどこに保存されているかを確認してください。これらのオブジェクトが必要なときにリリースされていることを確認してください。これらの外部オブジェクトをどこに配置するかを把握し、それらが時間どおりにリリースされることを確認してください。「リリースされた」とは、単にそれらの値を。で上書きすることを意味しますnil
。
スクリプトとソースコードの間に絶縁層を構築します。LuaにCocos2D-Xオブジェクトへのポインターを直接与えるのではなく、Cocos2D-Xオブジェクトへの参照を含む可能性のある特別なオブジェクトへのポインターを与えます。このように、このコントロールオブジェクトに参照を削除するように指示することで、これらのオブジェクトがいつ解放されるかを直接制御できます。Luaが空のコントロールオブジェクトを呼び出すと、関数は...無害なものを返します(クラッシュしないようにするため)。明らかに、Luaはそれが有効なコントロールオブジェクトであるかどうかを確認する関数を持っている必要があります。
Luaでやりたいことは何でもしますが、リソースを解放するときは、Luaの状態全体を破棄します。現在の方法は非常にきめ細かいものです。Luaはいくつかのリソースを作成し、Luaはそれらがいつなくなるかを決定します。より厳密なリソース管理スキームは、Luaスクリプトがいくつかのリソースと参照リソースをロードすることです。しかし、それらのリソースをすべて破壊するときは、あなた自身だけlua_close
ですlua_State
。これにより、すべての参照が解放され、それらのリソースが解放されます。問題が解決しました。