2016-12-19 16 views
3

スウィフトコードでNSUndoManagerProxyクラッシュをキャストNSUndoManager:我々は、次のコードを使用している我々のアプリケーションで

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

これは警告なしでコンパイルおよびMacOSの10.12シエラ下の罰金に実行されます。しかし、実行時に10.9 - 10.11(El CapitanまでMavericks)でクラッシュします。 クラッシュレポート通知:

は 'MyObjectType'(0x108b82218)にタイプ 'NSUndoManagerProxy'(0x7fff76d6d9e8)の値をキャストできませんでした。

それから私はにコードを書き直しました。そして、それはクラッシュしませんが、その後の取り消しはまったく機能していない

if let lInvocationTarget = lUndoManager.prepare(withInvocationTarget: self) as? MyObjectType { 
    let _ = lInvocationTarget.setOpacity(_: self.opacity, undoManager: lUndoManager) 
} 

。 この最後の書き方はApples documentationから直接的に出ているので、Swift 3または10.12 SDKの動作が明らかに変更されています。私はSwift 3とSDK 10.12でXcode 8.2を使用しています

もっと多くの引数を持つ他の取り消し可能なメソッドがたくさんあるので、registerUndo(withTarget、selector :, object :)は適切ではありません。本当に辞書にそれらをラップしたくない。そして、セレクタが今日はかなりタイプセーフですが、私はまだそれらを好きではありません。 ブロックベースのAPI(registerUndo(withTarget:handler :))もありますが、残念ながら10.11+のみです。

誰でも同じ問題が発生しましたか?さらに重要なことは誰もが出る方法を考え出すことです。

答えて

2

私はあなたの最初のコードのMacOS 10.12で動作すると聞いて驚いています。方法prepare(withInvocationTarget:)であり、これはほとんど動作しないSwiftものです。返されたプロキシオブジェクトは元のクラスのインスタンスではなく、オブジェクトもいずれも元のOS Xの一部であるNSObjectの子孫ではありません。

とにかく、これは試してみる価値一つのことです。私もANYOBJECTにキャストすることは:-)をコンパイルすることを驚いてる

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

。 AnyObjectで呼び出された未知のメソッドに対するコンパイラの警告を期待していましたか?しかし、私はあなたのソリューションの動作を確認することができます! – Marius

+0

私はこの解決策が私にとってもうまくいくことを確認できますが(最初はなぜエラーが出るのか疑問ですが)、NSObjectとして 'MyObjectType'を宣言する必要があることを付け加えたいと思います。 'class MyObjectType {...}'を宣言するとコンパイルエラー "型の値 'AnyObject'にメンバー 'myMethod'がありません。 – HuaTham

関連する問題