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
是一个结构。
闭包内的代码永远不会执行。最初我注意到 undoManager
是 nil
,但后来我发现了这个片段:
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
不会被过早捕获。
我正在尝试在我的模型中实施 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
是一个结构。
闭包内的代码永远不会执行。最初我注意到 undoManager
是 nil
,但后来我发现了这个片段:
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
不会被过早捕获。