You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4.0中创建Selector并调用函数是否有更优Swift风格实现方式?

Swift 4+ 风格的 Status Bar Button 回调实现

嘿,你的问题提得很到位!首先得明确:你现在用的#selector写法其实已经是Swift 4+里推荐的现代风格了,并没有过时~不过我们可以聊聊细节优化,以及有没有更贴合Swift编程习惯的实现方式。

1. 先聊聊你当前的写法

你用的#selector(myFunction)是Swift 4引入的类型安全Selector语法,替代了之前容易出错的字符串形式(比如Selector("myFunction:"))——它能在编译阶段就检查函数是否存在,大大降低了运行时崩溃的风险,这本身就是Swift 4+的最佳实践之一。

这里的@objc修饰符是必须的:因为NSStatusBarButton是基于Objective-C的Cocoa API,需要把Swift函数暴露给Objective-C运行时才能被调用。如果不需要用到sender参数,还可以简化代码:

button.action = #selector(myFunction)
@objc func myFunction() { 
    print("Hi") 
}

2. 更贴合Swift风格的闭包回调方式

如果你觉得Target-Action模式太有“Objective-C味儿”,可以给NSStatusBarButton写一个扩展,让它支持闭包回调——这种方式更符合Swift的闭包编程习惯,不用额外写@objc函数,代码逻辑也更集中:

extension NSStatusBarButton {
    private struct AssociatedKeys {
        static var actionClosure = "ActionClosure"
    }

    // 给按钮添加闭包属性
    var actionClosure: (() -> Void)? {
        get {
            return objc_getAssociatedObject(self, &AssociatedKeys.actionClosure) as? () -> Void
        }
        set {
            objc_setAssociatedObject(self, &AssociatedKeys.actionClosure, newValue, .OBJC_ASSOCIATION_RETAIN_NONATOMIC)
            // 将按钮自身设为target,绑定内部转发函数
            self.target = self
            self.action = #selector(handleAction)
        }
    }

    // 内部转发用的@objc函数,对外不可见
    @objc private func handleAction() {
        actionClosure?()
    }
}

使用的时候就非常简洁了:

button.actionClosure = {
    print("Hi")
}

总结

  • 你当前的#selector写法是标准且安全的,完全没有过时;
  • 如果想要更“Swift化”的实现,闭包扩展是很好的选择,既保持了类型安全,又让代码更紧凑。

内容的提问来源于stack exchange,提问作者Jared Pieniazek

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:29:19