删除 WebView 的 NSUndoManager 的撤消操作
我有几个 WebView,可以在视图层次结构中换入和换出。其中一些 WebView 包含表单字段,因此我实现 EditingDelegate 来为我的文档提供 NSUndoManager。
问题在于,在 WebView 中完成的任何键入都会生成放置在撤消堆栈上的操作。从层次结构中删除视图后,操作仍位于撤消堆栈中。此时,如果用户使用 Cmd-Z 来“撤消键入”,则会引发异常,因为 -undoEditing: 被发送到 WebEditorUndoTarget 的已释放实例。 (WebKit 实现中使用的私有类。)
我无法使用 -removeAllActionsWithTarget: 因为我无法引用目标。看来唯一的解决方案是禁用 WebView 的撤消注册。
我是否遗漏了什么或者这是 WebView 的限制?
I have several WebViews that I swap in and out of my view hierarchy. Some of these WebViews contain form fields, so I implement the editingDelegate to provide the NSUndoManager for my document.
The problem is that any typing done in the WebView generates actions that are placed on the undo stack. After the view is removed from the hierarchy, the actions are still in the undo stack. At that point, if a user uses Cmd-Z to "Undo Typing", an exception is thrown because -undoEditing: is being sent to a deallocated instance of WebEditorUndoTarget. (A private class used in the WebKit implementation.)
I can't use -removeAllActionsWithTarget: because I can't reference the target. It appears the only solution is to disable undo registration for the WebView.
Am I missing something or is this a limitation of a WebView?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一种私有 API 解决方案是调用 -[WebView _clearUndoRedoOperations]。尚未找到公共 API 解决方案。
One private API solution is to invoke -[WebView _clearUndoRedoOperations]. Haven't found a public API solution yet.
在我看来,WebView 应该负责从 WebView 的 undoManager 中删除自身或任何从属对象:在本例中,是您的。
从你的描述来看,它不是这样做的。我怀疑你找到目标以便明确删除它的目标将是徒劳的,所以我想建议另一种解决方案,我以前使用过它,或者我已经在这条路上走得足够远来考虑使用 ; )
我对这种情况的想法是使用 NSUndoManager 的自定义子类,该子类能够保留其上所有注册的冗余内存(通过覆盖 registerUndoWithTarget:… 和prepareWithInitationTarget)。有了一系列值得信赖的所有注册,您就可以随时实施自己的清理政策。也就是说,您可能会说“如果目标的类来自我不拥有的框架,则将其删除”……或者更具体地说,您想要删除与 WebEditorUndoTarget 类匹配的任何内容。
In my opinion the WebView should take responsibility for removing itself or any subservient objects from the WebView's undoManager: in this case, yours.
Judging from your description, it's not doing this. I suspect that your aim to find the target so you can remove it explicitly will be fruitless, so I'd like to suggest another solution, which I've either used before, or I got far enough down this road to think about using ;)
The thought I had for this kind of situation is to use a custom subclass of NSUndoManager that is capable of keeping its own redundant memory of all the registrations upon it (by overriding registerUndoWithTarget:… and prepareWithInvocationTarget). With a trustable array of all the registrations, you could then impose your own policy for cleaning house at any time. I.e. you might say "if the target's class is from a framework I don't own, just remove it" … or be more specific and say you want to remove anything that matches the class WebEditorUndoTarget, for example.
上次我检查
NSUndoManager
有一个方法- (void)removeAllActions
。无需指定行动目标。Last time I checked the
NSUndoManager
had a method- (void)removeAllActions
. No need to specify action targets.