OS X 10.11上无法识别的选择器

时间:2017-01-09 10:07:06

标签: swift macos unrecognized-selector

我在系统状态栏中使用带有菜单的自定义项目来控制我的应用程序中的某些功能。这是我的代码:

import Foundation

class StatusBarMenuController {
    var statusItem: NSStatusItem

    init() {
        self.statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength)

        statusItem.image = NSImage(named: "StatusBarButtonImage")

        let menu = NSMenu()            
        let isListeningMenuItem = NSMenuItem(title: "Listening", action: #selector(StatusBarMenuController.isListeningAction(_:)), keyEquivalent: "")

        isListeningMenuItem.isAlternate = true
        isListeningMenuItem.target = self
        isListeningMenuItem.state = NSOnState

        menu.addItem(isListeningMenuItem)

        statusItem.menu = menu
    }

    @objc func isListeningAction(_ item: NSMenuItem) {            
        if (item.state == NSOffState) {
            item.state = NSOnState
            // Handle switch-on action...
        }
        else {
            item.state = NSOffState
            // Handle switch-off action...
        }
    }
}

此类在applicationDidFinishLaunching的{​​{1}}方法中实例化。

所有在最新版本的macOS(10.12)上工作正常 - 我在多台计算机上尝试过,但是当尝试在具有旧版本操作系统的计算机上启动应用程序时,例如OS X 10.11,它立即崩溃。

崩溃详情:

  

特定应用信息:   无法识别的选择器 - [MyAppName.StatusBarMenuController methodForSelector:]

     

abort()调用

任何想法为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

NSObject派生解决了这个问题:

import Foundation

class StatusBarMenuController: NSObject {
    var statusItem: NSStatusItem

    override init() {
        self.statusItem = NSStatusBar.system().statusItem(withLength: NSSquareStatusItemLength)

        super.init()

        statusItem.image = NSImage(named: "StatusBarButtonImage")

        let menu = NSMenu()            
        let isListeningMenuItem = NSMenuItem(title: "Listening", action: #selector(StatusBarMenuController.isListeningAction(_:)), keyEquivalent: "")

        isListeningMenuItem.isAlternate = true
        isListeningMenuItem.target = self
        isListeningMenuItem.state = NSOnState

        menu.addItem(isListeningMenuItem)

        statusItem.menu = menu
    }

    @objc func isListeningAction(_ item: NSMenuItem) {            
        if (item.state == NSOffState) {
            item.state = NSOnState
            // Handle switch-on action...
        }
        else {
            item.state = NSOffState
            // Handle switch-off action...
        }
    }
}

这是一个非常奇怪的行为,因为在我的应用程序的其他部分,我在非NSObject派生类中使用带NotificationCenter的选择器并且它可以工作,例如:

class StatusBarMenuController {
    NotificationCenter.default.addObserver(
        self,
        selector: #selector(handleMyNotification),
        name: NSNotification.Name(rawValue: myNotification),
        object: nil
    )

    @objc func handleMyNotifiction(_ notification: Notification) {
        // ...
    } 
}