正如标题所说,当我的状态栏菜单打开并且从另一个线程触发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 :(得分:1)
在我的情况下,解决方案是在显示警告之前关闭菜单。
我必须访问menu
的{{1}}媒体资源中的菜单,然后致电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()
}
}