在我们的应用程序中,我们使用以下代码:
let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
let _ = (lInvocationTarget as! MyObjectType).myMethod(_: self.opacity, undoManager: lUndoManager)
这编译没有警告,并在macOS 10.12 Sierra下正常运行。然而它在10.9 - 10.11(Mavericks直到El Capitan)的运行时崩溃了。 崩溃报告通知:
无法将“NSUndoManagerProxy”类型的值(0x7fff76d6d9e8)转换为“MyObjectType”(0x108b82218)。
然后我将代码改写为:
if let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self) as? MyObjectType {
let _ = lInvocationTarget.setOpacity(_: self.opacity, undoManager: lUndoManager)
}
然后它不会崩溃,但是撤消根本不起作用。 最后一种写法直接来自Apples documentation,因此在Swift 3或10.12 SDK中显然改变了行为。我正在使用Xcode 8.2和Swift 3以及SDK 10.12
registerUndo(withTarget,selector:,object :)不合适,因为我有很多其他可撤销方法和更多参数。真的不想把那些包在字典中的orso。即使选择器现在非常安全,我仍然不喜欢它们。 还有基于块的API(registerUndo(withTarget:handler :)),但不幸的是只有10.11 +。
有人遇到过同样的问题吗?更重要的是:有人想出办法吗?
答案 0 :(得分:3)
我非常惊讶于我在macOS 10.12上听到您的第一个代码正常工作。方法prepare(withInvocationTarget:)
一直是这个 - 难以在Swift中工作的东西。不仅返回的代理对象不是原始类的实例,而且对象也不是NSObject
的后代(在某些以前的OS X中至少是这样)。
无论如何,这是值得一试的事情:
let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
_ = (lInvocationTarget as AnyObject).myMethod(self.opacity, undoManager: lUndoManager)
答案 1 :(得分:0)
我发现 registerUndoWithTarget:handler:现在是一个更好的API。