2016-09-21 78 views
0

正如标题所示,当我的状态栏菜单打开并且另一个线程触发NSAlert时,UI会冻结。当NSMenu打开时出现NSAlert会导致UI冻结

大概这是因为这两个东西都在主线程上运行。但由于我正在处理NSAlert和NSMenu,我不是在主线程上运行这些吗?

NSAlert代码

func showWallpaperUpdateErrorAlert(messageText: String, informativeText: String) { 
    DispatchQueue.main.async { 
     NSApp.activate(ignoringOtherApps: true) 

     let updateErrorAlert = NSAlert() 
     updateErrorAlert.messageText = messageText 
     updateErrorAlert.informativeText = informativeText 
     updateErrorAlert.addButton(withTitle: "OK") 
     updateErrorAlert.runModal() 
    } 
} 

NSMenu代码

func createStatusBarMenu() { 
    // Status bar icon 
    guard let icon = NSImage(named: "iconFrame44") 
     else { NSLog("Error setting status bar icon image."); return } 
    icon.isTemplate = true 
    statusBarItem.image = icon 

    // Create Submenu items 
    let viewOnRedditMenuItem = NSMenuItem(title: "View on Reddit...", action: #selector(viewOnRedditAction), keyEquivalent: "") 
    viewOnRedditMenuItem.target = self 

    let saveThisImageMenuItem = NSMenuItem(title: "Save This Image...", action: #selector(saveThisImageAction), keyEquivalent: "") 
    saveThisImageMenuItem.target = self 

    // Add to title submenu 
    let titleSubmenu = NSMenu(title: "") 
    titleSubmenu.addItem(descriptionMenuItem) 
    titleSubmenu.addItem(NSMenuItem.separator()) 
    titleSubmenu.addItem(viewOnRedditMenuItem) 
    titleSubmenu.addItem(saveThisImageMenuItem) 

    // Create main menu items 
    titleMenuItem = NSMenuItem(title: "No Wallpaperer Image", action: nil, keyEquivalent: "") 
    titleMenuItem.submenu = titleSubmenu 
    titleMenuItem.isEnabled = false 
    getNewWallpaperMenuItem = NSMenuItem(title: "Update Now", action: #selector(getNewWallpaperAction), keyEquivalent: "") 
    getNewWallpaperMenuItem.target = self 

    let preferencesMenuItem = NSMenuItem(title: "Preferences...", action: #selector(preferencesAction), keyEquivalent: "") 
    preferencesMenuItem.target = self 

    let quitMenuItem = NSMenuItem(title: "Quit Wallpaperer", action: #selector(quitAction), keyEquivalent: "") 
    quitMenuItem.target = self 

    // Add to main menu 
    let statusBarMenu = NSMenu(title: "") 
    statusBarMenu.addItem(titleMenuItem) 
    statusBarMenu.addItem(NSMenuItem.separator()) 
    statusBarMenu.addItem(getNewWallpaperMenuItem) 
    statusBarMenu.addItem(NSMenuItem.separator()) 
    statusBarMenu.addItem(preferencesMenuItem) 
    statusBarMenu.addItem(quitMenuItem) 

    statusBarItem.menu = statusBarMenu 

    statusBarMenu.delegate = self 
} 
+0

嗨,你的OS X版本是什么?它是OS X 10.12(Sierra)? – DoN1cK

+0

是的,我在塞拉利昂。 – yesthisisjoe

回答

1

在我的情况的解决方案是显示警报之前关闭该菜单。

我不得不从NSStatusItemmenu物业访问菜单,并呼吁cancelTrackingWithoutAnimation()(经常cancelTracking()是不平稳)。无论出于何种原因,我还必须在主线外进行此操作。

func showWallpaperUpdateErrorAlert(messageText: String, informativeText: String) { 
    statusBarItem.menu?.cancelTrackingWithoutAnimation() // This is new 

    DispatchQueue.main.async { 
     NSApp.activate(ignoringOtherApps: true) 

     let updateErrorAlert = NSAlert() 
     updateErrorAlert.messageText = messageText 
     updateErrorAlert.informativeText = informativeText 
     updateErrorAlert.addButton(withTitle: "OK") 
     updateErrorAlert.runModal() 
    } 
} 
+0

它完成这项工作。 – DoN1cK

相关问题