NSUndoManager 是否保留对象?

发布于 2024-10-04 01:49:21 字数 715 浏览 6 评论 0原文

我执行以下操作:

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

我还有一个明确的按钮可以执行以下操作:

[undoManager removeAllActions];

问题是 removeAllActions 使应用程序崩溃。当我删除 [pathToRemove autorelease] 时,它起作用了(或者至少没有崩溃。它仍然可能是内存泄漏)。我想我假设 undoManager 在传递“prepareWithInitationTarget”调用时保留“pathToRemove”。

难道不是这样吗?如果情况并非如此,则可能会发生崩溃,因为对“removeAllActions”的调用正在释放“PathToRemove”对象。但这意味着这是 NSUndoManager 中的一个错误,这种可能性极小。

我可以说我的 copyWithZone 实现也不太可能是罪魁祸首,因为“[pathToRemove description]”和“[path description]”的 NSLog 输出按预期显示不同的地址。

任何帮助将不胜感激。谢谢。

I do the following:

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

I also have a clear button that does:

[undoManager removeAllActions];

Problem is that the removeAllActions crashes the app. When I removed the [pathToRemove autorelease], it worked (or at least didn't crash. It could still be a memory leak). I guess I was assuming that the undoManager retained 'pathToRemove' when passed in the 'prepareWithInvocationTarget' call.

Is that not the case? If that is not the case then the crash could happen because the call to 'removeAllActions' is releasing the 'PathToRemove' object. But that would mean it is a bug in NSUndoManager which is highly unlikely.

I can say that my copyWithZone implementation is not likely to be the culprit either since NSLog outputs for '[pathToRemove description]' and '[path description]' show different addresses as expected.

Any help would be appreciated. Thanks.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

余厌 2024-10-11 01:49:21

根据文档,prepareWithInitationTarget: 方法不保留传递给它的参数。来自 NSUndoManager 文档,它似乎只是捕获了 NSInvocau 并稍后重播它。除非特别要求,否则 NSInitation 对象不会保留其参数中的对象。

这并不能完全解释崩溃的原因,因为 removeAllActions 只是应该清除撤消堆栈而不对对象执行任何操作。

希望这有助于一些人追踪崩溃的根源。

According to the documentation, the prepareWithInvocationTarget: method doesn't retain the arguments passed to it. From the NSUndoManager documentation, it appears that it simply captures the NSInvocation and later replays it. NSInvocationobjects don't retain the objects in their arguments unless specifically asked to do so.

That doesn't quite explain the crash, because removeAllActions is just supposed to clear the undo stack and not do anything to the objects.

Hope this helps some in tracking down the source of the crash.

温柔女人霸气范 2024-10-11 01:49:21

根据我的经验,这不是释放/保留问题。您必须在撤消/重做操作后清除堆栈。为此,您可以为 NSUndoManagerDidUndoChangeNotification 通知注册 viewController:

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

然后清除指定方法上的堆栈:

- (void)clearUndoRedoStack {
    [undoManager removeAllActions];
}

In my experience, it's not a release/retain issue. You've to clear the stack after the Undo/Redo Operation. To do this you can register your viewController for the NSUndoManagerDidUndoChangeNotification notification:

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

and then clear the stack onto the specified method:

- (void)clearUndoRedoStack {
    [undoManager removeAllActions];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文