【问题标题】:EXC_BAD_ACCESS when an NSMenuItem's target/selector is set to an objectNSMenuItem 的目标/选择器设置为对象时的 EXC_BAD_ACCESS
【发布时间】:2018-08-07 08:58:27
【问题描述】:

我正在使用此类抽象 NSMenuItem:

class MenuItem{
    let title: String
    let iconName: String
    let action: Action
    init(title: String, iconName: String, _ action: @escaping Action) {
        self.title = title
        self.iconName = iconName
        self.action = action
    }

    @objc func doAction(sender: NSMenuItem){
        action()
    }
}

这是构建菜单的静态函数:

static func getMenu(items: [MenuItem]) -> NSMenu{
    let m = NSMenu()
    for x in items{
        let item = NSMenuItem()
        item.title = x.title
        item.target = x // If I remove this line or the line below, there won't be any crash
        item.action = #selector(MenuItem.doAction) 
        item.image = x.iconName.toImage()
        m.addItem(item)
    }

    return m
}

现在我的问题是无论何时显示上下文菜单,程序都会因 EXC_BAD_ACCESS 错误而崩溃。

但是,当我注释掉设置目标或操作的行时,问题就会消失(当然,菜单将无法点击)。

那么我该如何解决这个问题?谢谢。

编辑:

我应该说我已经尝试过这些事情:

  1. 使用#selector(x.doAction) 而不是#selector(MenuItem.doAction)
  2. 使用#selector(x.doAction(sender:))

此外,输出窗口中没有任何内容。这就是我在这里寻求帮助的原因。更糟糕的是,它涉及 EXC_BAD_ACCESS,鉴于内存应该由系统管理,我几乎无法理解。

【问题讨论】:

  • #selector(MenuItem.doAction) 更改为#selector(x.doAction)
  • 控制台崩溃时应该有错误信息。我猜它应该是“-[ProjectName.MenuItem doAction] 无法识别的选择器发送到实例”或类似的东西。删除#selector(MenuItem.doAction),然后重新编写它,让完成对您有所帮助。该方法的签名是错误的,因为您接受了当前选择器中不存在的参数 (sender:)。你也不应该写let item = MenuItem()而不是let item = NSMenuItem()吗?
  • @RakeshaShastri 我已经试过了。阅读我的编辑。谢谢。
  • @Larme 根本没有输出。另外,MenuItem 是我对 NSMenuItem 的抽象。

标签: swift macos nsmenu nsmenuitem


【解决方案1】:

所以问题是,我传递给静态 getMenu 函数的数组中的 items 在 getMenu 函数完成后被释放(很快之后是 popUpMenuWithEvent:forView)。

我通过对该数组的强引用解决了这个问题。

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    相关资源
    最近更新 更多