首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UndoManager in NSResponder子类(macOS)

UndoManager in NSResponder子类(macOS)
EN

Stack Overflow用户
提问于 2019-05-10 13:14:01
回答 1查看 395关注 0票数 0

我正试图在我的模型中实现撤销/重做。因此,我将我的模型类作为NSResponder的子类,然后实现如下:

注意事项:此代码是根据注释后的更多研究编辑的。

代码语言:javascript
复制
func setAnnotations(_ newAnnotations: [Annotation]) {
    let currentAnnotations = self.annotations

    self.undoManager.registerUndo(withTarget: self, handler: { (selfTarget) in
        selfTarget.setAnnotations(currentAnnotations)
    })

    self.annotations = newAnnotations
}

Annotation是一个结构。

闭包中的代码永远不会被执行。一开始我注意到undoManagernil,但后来我发现了这个片段:

代码语言:javascript
复制
private let _undoManager = UndoManager()
override var undoManager: UndoManager {
   return _undoManager
}

现在undoManager不再是零了,但是闭包中的代码仍然没有被执行。

我在这里错过了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-10 14:59:18

我无法重现任何问题,既然您已经使您的撤销注册代码有意义。下面是测试应用程序的全部代码(我不知道注释是什么,所以我只使用了字符串):

代码语言:javascript
复制
import Cocoa
class MyResponder : NSResponder {
    private let _undoManager = UndoManager()
    override var undoManager: UndoManager {
        return _undoManager
    }
    typealias Annotation = String
    var annotations = ["hello"]
    func setAnnotations(_ newAnnotations: [Annotation]) {
        let currentAnnotations = self.annotations
        self.undoManager.registerUndo(withTarget: self, handler: { (selfTarget) in
            selfTarget.setAnnotations(currentAnnotations)
        })
        self.annotations = newAnnotations
    }
}

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
    let myResponder = MyResponder()
    @IBOutlet weak var window: NSWindow!
    func applicationDidFinishLaunching(_ aNotification: Notification) {
        print(self.myResponder.annotations)
        self.myResponder.setAnnotations(["howdy"])
        print(self.myResponder.annotations)
        self.myResponder.undoManager.undo()
        print(self.myResponder.annotations)
    }
}

产出如下:

代码语言:javascript
复制
["hello"]
["howdy"]
["hello"]

所以撤销是完美的。如果这种情况没有发生在您身上,那么您可能在某种程度上对您的“模型类”管理不善。

顺便说一句,写注册结束语的一个更正确的方法是:

代码语言:javascript
复制
    self.undoManager.registerUndo(withTarget: self, handler: {
        [currentAnnotations = self.annotations] (selfTarget) in
        selfTarget.setAnnotations(currentAnnotations)
    })

这确保了self.annotations不会过早地被捕获。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56078473

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档