您需要对项目的目标进行非弱引用。
试试这个:
// Define this in your class.
static let itemTarget = CustomToolbarButton(itemIdentifier: "myButton")
// and use it when setting the target in the constructor.
self.target = CustomToolbarButton.itemTarget
来自 docs.swift.org
“弱引用是一种不会对其引用的实例保持强控制的引用,因此不会阻止 ARC 处理引用的实例。”
如果对实例的所有引用都是弱引用,则会自动创建并释放该项目。您需要至少一个非弱引用来保留实例。
推荐阅读:
https://docs.swift.org/swift-book/LanguageGuide/AutomaticReferenceCounting.html
另外,就像你说的,@objc 指令在动作函数中是必需的。
这里有一些有用的链接。
'#selector' 指的是没有暴露给 Objective-C 的方法
'#selector' refers to a method that is not exposed to Objective-C
查看选择器表达式
https://docs.swift.org/swift-book/ReferenceManual/Expressions.html
最后这里是一个关于 Xcode 10.3 和 Swift 5 的工作示例:
// Created by Juan Miguel Pallares Numa on 9/12/19.
// Copyright © 2019 Juan Miguel Pallares Numa. All rights reserved.
import Cocoa
@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {
// Strong reference.
var myWindowController = WindowController()
func applicationDidFinishLaunching(_ aNotification: Notification) {
myWindowController.makeWindowKeyAndOrderFront()
}
}
import Cocoa
class ToolbarController: NSObject, NSToolbarDelegate {
let identifiers = [NSToolbarItem.Identifier("myIdentifier")]
let toolbar = NSToolbar()
let toolbarItem: NSToolbarItem
override init() {
toolbarItem = NSToolbarItem(itemIdentifier: identifiers[0])
super.init()
toolbar.delegate = self
toolbarItem.label = "Print My Console Message"
toolbarItem.target = self
toolbarItem.action = #selector(
ToolbarController.toolbarAction(_:))
toolbarItem.image = NSImage(named: NSImage.applicationIconName)!
}
@objc func toolbarAction(_ sender: Any?) {
print("Hello world")
}
func toolbarAllowedItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbarDefaultItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbarSelectableItemIdentifiers(_ toolbar: NSToolbar) -> [NSToolbarItem.Identifier] {
return identifiers
}
func toolbar(_ toolbar: NSToolbar,
itemForItemIdentifier itemIdentifier: NSToolbarItem.Identifier,
willBeInsertedIntoToolbar flag: Bool) -> NSToolbarItem? {
return toolbarItem
}
}
import Cocoa
class WindowController: NSWindowController {
var toolbarController = ToolbarController()
convenience init() {
let window = NSWindow(
contentViewController: ViewController())
self.init(window: window)
window.toolbar = toolbarController.toolbar
}
func makeWindowKeyAndOrderFront() {
window?.makeKeyAndOrderFront(nil)
}
}
import Cocoa
class ViewController: NSViewController {
override func loadView() {
view = NSView(frame: NSRect(x: 0, y: 0, width: 400, height: 300))
}
}