NSUndoManager 转换 NSUndoManagerProxy 在 Swift 代码中崩溃
NSUndoManager casting NSUndoManagerProxy crash in Swift code
在我们的应用程序中,我们使用以下代码:
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)的运行时崩溃。
崩溃报告通知:
Could not cast value of type 'NSUndoManagerProxy' (0x7fff76d6d9e8) to '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:) 不适合,因为我有很多其他参数更多的可撤消方法。真的不想将它们包装在字典中。即使现在选择器类型安全,我仍然不喜欢它们。
还有基于块的 API (registerUndo(withTarget: handler:) ),但不幸的是,这仅适用于 10.11+.
有人遇到过同样的问题吗?更重要的是:有人想出出路吗?
听到您的第一个代码 works on macOS 10.12,我感到非常惊讶。方法 prepare(withInvocationTarget:)
一直是 this-hardly-works-in-Swift 的事情。不仅返回的代理对象不是原始 class 的实例,而且该对象也不是 NSObject
的后代(至少在某些以前的 OS X 中)。
无论如何,这是一件值得尝试的事情:
let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
_ = (lInvocationTarget as AnyObject).myMethod(self.opacity, undoManager: lUndoManager)
我发现 registerUndoWithTarget:handler: 现在更好 API。
在我们的应用程序中,我们使用以下代码:
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)的运行时崩溃。 崩溃报告通知:
Could not cast value of type 'NSUndoManagerProxy' (0x7fff76d6d9e8) to '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:) 不适合,因为我有很多其他参数更多的可撤消方法。真的不想将它们包装在字典中。即使现在选择器类型安全,我仍然不喜欢它们。 还有基于块的 API (registerUndo(withTarget: handler:) ),但不幸的是,这仅适用于 10.11+.
有人遇到过同样的问题吗?更重要的是:有人想出出路吗?
听到您的第一个代码 works on macOS 10.12,我感到非常惊讶。方法 prepare(withInvocationTarget:)
一直是 this-hardly-works-in-Swift 的事情。不仅返回的代理对象不是原始 class 的实例,而且该对象也不是 NSObject
的后代(至少在某些以前的 OS X 中)。
无论如何,这是一件值得尝试的事情:
let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
_ = (lInvocationTarget as AnyObject).myMethod(self.opacity, undoManager: lUndoManager)
我发现 registerUndoWithTarget:handler: 现在更好 API。