NSResponder 子类中的 UndoManager (macOS)

UndoManager in NSResponder subclass (macOS)

我正在尝试在我的模型中实施 undo/redo。所以我让我的模型 class 成为 NSResponder 的子 class,然后实现了以下内容:

注意:此代码是根据评论后的更多研究编辑的

func setAnnotations(_ newAnnotations: [Annotation]) {
    let currentAnnotations = self.annotations

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

    self.annotations = newAnnotations
}

Annotation 是一个结构。

闭包内的代码永远不会执行。最初我注意到 undoManagernil,但后来我发现了这个片段:

private let _undoManager = UndoManager()
override var undoManager: UndoManager {
   return _undoManager
}

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

我在这里错过了什么?

既然您已经使撤消注册代码变得有意义,我就无法重现任何问题。这是测试应用程序的 完整 代码(我不知道 Annotation 是什么,所以我只使用了 String):

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)
    }
}

输出为:

["hello"]
["howdy"]
["hello"]

所以撤消操作非常完美。如果您没有遇到这种情况,可能是您在某些方面对 "model class" 管理不善。


顺便说一句,更正确的写你的注册闭包是这样的:

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

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