10
EventManager
クラスはC++で書かれており、Pythonに公開されています。これは、Pythonの側から使用するために、私が意図する方法である:Boost.Python:クラス関数へのコールバック
class Something:
def __init__(self):
EventManager.addEventHandler(FooEvent, self.onFooEvent)
def __del__(self):
EventManager.removeEventHandler(FooEvent, self.onFooEvent)
def onFooEvent(self, event):
pass
(add-
とremove-
がEventManager
の静的関数として公開されている。)
上記のコードに問題がコールバックすることですboost::python::object
インスタンス内に取り込まれます。私がself.onFooEvent
を実行すると、参照カウントがself
に増加し、削除されないので、デストラクタが呼び出されないので、イベントハンドラは決して削除されません(アプリケーションの最後を除いて)。
このコードは、self
引数を持たない関数(つまり、フリー関数または静的関数)ではうまく機能します。参照カウントを増やさないように、Python関数オブジェクトをどのようにキャプチャする必要がありますか?私はオブジェクトに弱い参照が必要です。
とにかく '__del__'に頼るべきではありません。代わりに、定期的なメソッドを公開してイベントハンドラを削除します。 (おそらく、 'x = Something(); use(x);#のようなコードがあれば、[コンテキストマネージャ](http://docs.python.org/library/stdtypes.html#context-manager-types) xはこの時点から未使用でなければならない ') – delnan
@delnanしかし、' Something'に似たクラスのオブジェクトは、別のC++マネージャに渡されます。そのマネージャはもはやそれらを必要としなくなると、それを削除します。私はこのコンテキストマネージャーでコンテキストマネージャーを使うことはできないと思う。 –
ああ、コンテキストマネージャの提案を無視してください。それでも、(またはむしろ)削除する代わりに、イベントハンドラを削除するように伝えるだけでよいのです。そうしないと、メモリ管理をよりスマートにする次のパッチがコードリークを引き起こす可能性があります。 – delnan