NSUndoManager在Swift代码中转换NSUndoManagerProxy崩溃 [英] NSUndoManager casting NSUndoManagerProxy crash in Swift code

查看:151
本文介绍了NSUndoManager在Swift代码中转换NSUndoManagerProxy崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的应用程序中,我们使用以下代码:

In our application we're using the following code:

let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
let _ = (lInvocationTarget as! MyObjectType).myMethod(_: self.opacity, undoManager: lUndoManager)

它可以编译而不会发出警告,并且可以在macOS 10.12 Sierra上正常运行.但是,它在运行时在10.9-10.11(小牛直到El Capitan)崩溃. 崩溃报告注意:

This compiles without warnings and runs fine under macOS 10.12 Sierra. However it crashes at runtime on 10.9 - 10.11 (Mavericks till El Capitan). The crash report notices:

无法将类型为"NSUndoManagerProxy"(0x7fff76d6d9e8)的值强制转换为"MyObjectType"(0x108b82218).

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

然后它不会崩溃,但是撤消完全不起作用. 这最后一种书写方式直接来自 Apple文档,因此显然行为在Swift 3或10.12 SDK中已更改.我正在使用带有Swift 3和SDK 10.12的Xcode 8.2

Then it doesn't crash, but then Undo is not working at all. This last way of writing comes directly out of Apples documentation, so apparently behaviour changed in Swift 3 or 10.12 SDK. I'm using Xcode 8.2 with Swift 3 and SDK 10.12

registerUndo(withTarget,选择器:,对象:)不适合,因为我还有许多其他的带有更多参数的可撤销方法.真的不想将它们包装在字典中.即使现在选择器非常安全,我仍然不喜欢它们. 还有基于块的API(registerUndo(withTarget:handler :)),但是不幸的是,仅适用于10.11 +.

The registerUndo(withTarget, selector:, object:) is not suitable because I have a lot of other undoable methods with more arguments. Really don't want to wrap those in a dictionary orso. And even when selectors are pretty type safe nowadays, I still don't like them. There is also the block based API (registerUndo(withTarget: handler:) ), but that is unfortunately only for 10.11+.

有人遇到同样的问题吗?更重要的是:有人想出办法吗?

Anyone encountered the same problem? And more important: anyone come up with a way out?

推荐答案

我非常惊讶,我听到您的第一个代码在MacOS 10.12上有效.方法prepare(withInvocationTarget:)一直是 Swift很难工作的东西.不仅返回的代理对象不是原始类的实例,而且该对象也不是NSObject的后代(在某些以前的OS X中是租借的).

I am so much astonished that I hear your first code works on macOS 10.12. The method prepare(withInvocationTarget:) has been a this-hardly-works-in-Swift thing. Not only the returned proxy object is not the instance of the original class, but neither the object is not a descendent of NSObject (at lease in some former OS Xs).

无论如何,这是一件事值得尝试:

Anyway, this is one thing worth trying:

let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self)
_ = (lInvocationTarget as AnyObject).myMethod(self.opacity, undoManager: lUndoManager)

这篇关于NSUndoManager在Swift代码中转换NSUndoManagerProxy崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆