2016-07-07 15 views
4

NSApplicationの独自のサブクラスを作成していて、ロードブロッキングを実行中です。ここにrun()メソッドの実装があります。私main.swiftカスタムNSApplicationで作成したNSWindowが閉じない

override func run() { 
    finishLaunching() 
    repeat { 

     let event = nextEventMatchingMask(0xfffffffffffffff, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 
     if event != nil { sendEvent(event!) } 
     updateWindows() 

    } while true 

} 

私はこれを持っている:私はIntUInt64から変換されたときの代わりInt(NSEventMask.AnyEventMask.rawValue)0xfffffffffffffffは後者のオーバーフローためである持っている理由

let myApp: MyApplication = MyApplication.sharedApplication() as! MyApplication 

let window = NSWindow(contentRect: NSMakeRect(0, 0, 100, 100), styleMask: NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask , backing: .Buffered, defer: false) 
window.makeKeyAndOrderFront(nil) 

myApp.run() 

理由。

問題は、赤い閉じるボタンをクリックするとウィンドウが閉じず、ドックアイコンメニューから「終了」を選択すると終了しないという問題です。なぜこれが起こるのですか?

EDIT:同じ問題がthis answer.

EDIT 2で説明されています。私は、このコードのObjective-Cのバージョンを作成しましたし、すべてが正常に動作します。問題は、SwiftでNSAnyEventMaskを使用できないということです。

答えて

0

私はこの問題を解決したようですが、Objective-Cではこれを使うだけで、私のアプリケーションはドックメニューの終了項目に応答します。スウィフトは

NSEvent *event = [NSApp nextEventMatchingMask:NSAnyEventMask 
            untilDate:nil 
             inMode:NSDefaultRunLoopMode 
             dequeue:YES]; 

あなたはこれだろうそのように次のイベントを取得しようとします

let event = nextEventMatchingMask(Int(NSEventMask.AnyEventMask.rawValue), 
            untilDate: NSDate.distantPast(), 
            inMode: NSDefaultRunLoopMode, 
            dequeue: true) 

をintにUInt64型から変換するときただし、オーバーフローエラーが発生します。これは意図しないようです。まず、この問題を0xfffffffffffffffに置き換えて解決しようとしました。これは正常に動作し、アプリケーションはイベントに応答します。しかし、これでは十分ではありませんでした。アプリはマスク0x1に一致するイベントにも応答する必要があります。なぜ私は考えていませんが、これで私のアプリケーションを終了してドックメニューから隠すことができます。 (0x0は私だけで終了することができます。)

はそれでは、スウィフトNSApplicationのサブクラスの全体run()実装は、これは次のとおりです。

override func run() { 
    finishLaunching() 
    setValue(true, forKey: "running") 

    while true { 
     let event = nextEventMatchingMask(0xfffffffffffffff, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 
     let dockEvent = nextEventMatchingMask(0x1, untilDate: NSDate.distantPast(), inMode: NSDefaultRunLoopMode, dequeue: true) 

     if dockEvent != nil { sendEvent(dockEvent!) } 
     if event != nil { sendEvent(event!) } 

     if !running { break } 

     updateWindows() 
    } 
} 
1

self.runningの間だけ繰り返してください。それはあなたのアプリがなぜ終了しないのかを説明するかもしれません。最後のウィンドウが閉じられたときにアプリケーションが終了するように設定されている場合は、ウィンドウが閉じない理由を説明することもできます。とにかく、アプリケーション全体が終了する場合、フレームワークは別々にウィンドウを閉じることを心配しないかもしれません。

+0

問題があり、どのようなことはありませんが、それは実行しませんさ。 'super.run()'を呼び出さずに 'running'を明示的に設定することはできません –

+0

Hmm。 Appleの古い[GLUTサンプルコード](https://developer.apple.com/legacy/library/samplecode/glut/Listings/GLUTApplication_m.html)は、スーパークラスの '_running'インスタンス変数を直接設定していることがわかりました。スウィフトはおそらく許されません。ですから、あなたはKVCを使って 'setValue(true、forKey:" running ")'しようとすることができます。 –

+0

これまで私は正直言って聞いたことがありませんが、あなたはそれをコードサンプルに入れることができますか?あなたが置いたものを貼り付けることはできません。 - 私が言ったことを気にしないでください。しかし、それはsyillが効きません。 –

関連する問題