EXC_BAD_ACCESS, когда цель/селектор NSMenuItem установлен на объект

Я абстрагирую 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, что я с трудом могу понять, учитывая, что память должна управляться системой.


person Sid Go    schedule 07.08.2018    source источник
comment
Изменить #selector(MenuItem.doAction) на #selector(x.doAction)   -  person Rakesha Shastri    schedule 07.08.2018
comment
При сбое в консоли должно быть сообщение об ошибке. Я предполагаю, что это должен быть -[ProjectName.MenuItem doAction] нераспознанный селектор, отправленный в экземпляр или что-то в этом роде. Удалите #selector(MenuItem.doAction) и напишите его снова, чтобы завершение помогло вам. Подпись метода неверна, потому что вы принимаете параметр (sender:), которого нет в вашем текущем селекторе. Также не следует ли вам писать let item = MenuItem() вместо let item = NSMenuItem()?   -  person Larme    schedule 07.08.2018
comment
@RakeshaShastri Я уже пробовал это. Прочтите мои правки. Спасибо.   -  person Sid Go    schedule 07.08.2018
comment
@Larme Выхода нет вообще. Кроме того, MenuItem — это моя абстракция NSMenuItem.   -  person Sid Go    schedule 07.08.2018


Ответы (1)


Итак, проблема в том, что items внутри массива, который я передаю статической функции getMenu, освобождается после завершения функции getMenu (за которой очень скоро следует popUpMenuWithEvent:forView).

Я решил это, имея сильную ссылку на этот массив.

person Sid Go    schedule 07.08.2018