2010-11-23 6 views
0

は、私は次の操作を行います。NSUndoManagerはオブジェクトを保持していますか?

[undoManager removeAllActions]; 

問題がremoveAllActionsアプリをクラッシュしていることである:

Path2D *pathToRemove = [path copy]; 
    [[[self undoManager] prepareWithInvocationTarget:self] removePath:pathToRemove atIndex:index]; 
[pathToRemove autorelease]; 

は私もないクリアボタンがあります。私は[pathToRemove autorelease]を削除したときに動作しました(または少なくともクラッシュしませんでしたが、メモリリークの可能性があります)。私は、 'prepareWithInvocationTarget'コールで渡されたときにundoManagerが 'pathToRemove'を保持していると仮定していたと思います。

そうではありませんか?そうでない場合、 'removeAllActions'の呼び出しが 'PathToRemove'オブジェクトを解放しているため、クラッシュが発生する可能性があります。しかし、それはNSUndoManagerのバグである可能性は非常に低いです。

私のcopyWithZone実装は、 '[pathToRemove description]'と '[path description]'のNSLog出力が異なるアドレスを期待どおりに表示していると考えられます。

ご協力いただければ幸いです。ありがとう。

+0

OK、私はそれを考え出しました。 'prepareWithInvokationTarget'は引数を保持します。私の問題は、私のcopyWithZoneメソッドが本当に間違っていたということでした。私はコピーされておらず、保持されていただけのオブジェクトを持っていました。したがって、 'R​​emoveAllActions'がオブジェクトを解放し、それぞれのDeallocメソッドに入ったとき、このメンバー変数の「コピー」されなかったリリースは、二重リリースシナリオを作成し、クラッシュを引き起こしました。再度、感謝します! – user482393

答えて

2

ドキュメントによると、prepareWithInvocationTarget:メソッドは、渡された引数を保持しません。 NSUndoManagerのドキュメントから、単にNSInvocationをキャプチャして後で再生するように見えます。 NSInvocationオブジェクトは特に要求されない限り、オブジェクトを引数に保持しません。 は、元に戻すスタックをクリアしてオブジェクトに何もしないと仮定されているため、クラッシュについてはあまり説明されていません。

これは、クラッシュの原因を特定するのに役立ちます。

+0

ありがとうございます。 registerUndoWithTarget:selector:objectを使って試してみよう。ドキュメントによると、これはオブジェクトを保持するので、この登録メソッドを呼び出した後に解放できるはずです。 – user482393

+0

これは正しくない、prepareWithInvocationTarget *はすべての引数を保持しますが、ターゲットを保持しません*。 – strange

0

私の経験上、リリース/保持の問題ではありません。あなたは元に戻す/やり直し操作の後にスタックをクリアしなければなりません。これを行うには、NSUndoManagerDidUndoChangeNotification通知のためのあなたのViewController登録することができます。

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(clearUndoRedoStack) name:NSUndoManagerDidUndoChangeNotification object:nil]; 

をして、指定したメソッドにスタックをクリア:

- (void)clearUndoRedoStack { 
    [undoManager removeAllActions]; 
} 
関連する問題