【发布时间】:2017-08-21 03:57:17
【问题描述】:
我在采用更复杂的基于调用的方法来撤消 Swift 中的注册时遇到了麻烦(基于 NSHipster 文章 here。Apple 的文档仍然包含 Objective-C 中的所有示例代码,并且语义对于调用设置)。
我的NSDocument 子类Document 具有以下对模型对象进行操作的方法,我希望将其设为可撤消:
func rename(object: Any, to newName: String) {
// This is basically a protocol that requires implementing:
// var name: String { get set }
//
guard var namedObject = object as? EditorHierarchyDisplayable else {
return
}
// Register undo:
let undoController = undoManager?.prepare(withInvocationTarget: self) as? Document
undoController?.rename(object: namedObject, to: namedObject.name)
undoManager?.setActionName("Rename \(namedObject.localizedClassName)")
// Perform the change:
namedObject.name = newName
}
我发现上面的undoController 是nil,因为尝试转换为Document 失败。如果我删除演员表(并注释掉对undoController.rename(... 的调用),prepare(withInvocationTarget:) 将返回以下对象:
(lldb) print undoController
(Any?) $R0 = some {
payload_data_0 = 0x00006080000398a0
payload_data_1 = 0x0000000000000000
payload_data_2 = 0x0000000000000000
instance_type = 0x000060800024f0d8
}
(lldb) print undoController.debugDescription
(String) $R1 = "Optional(NSUndoManagerProxy)"
(lldb)
我错过了什么?
【问题讨论】:
-
prepare(withInvocationTarget:)的文档说“返回自我”。self是undoManager。在 NSHipster 文章的底部写着“本文使用 Swift 1.0 版。”。 -
是的,文档也是如此。但它将返回的值转换为
as ViewController(我假设这变成了Document)。此外,as在 Swift 2+ 中变为as? -
将
NSUndoManager转换为Document是错误的。 Swift 1 不在乎,但 Swift 3 拒绝这样做。 -
那么,我如何在返回的代理上调用我的
Document方法rename(object:to:)呢? Objective-C 允许你向任何对象发送任何消息(至少在编译时),但是 Swift 是强类型的......
标签: swift cocoa nsundomanager